New Upstream Snapshot - liblocales-perl
Ready changes
Summary
Merged new upstream version: 0.34+git20180627.1.d00f65b+ds (was: 0.34+ds).
Resulting package
Built on 2023-01-20T06:59 (took 5m30s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-snapshots liblocales-perl
Diff
diff --git a/Changes b/Changes
index 9f3372d..99b5940 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,10 @@
Revision history for Perl distribution Locales
+0.35 ???
+ - Add meta-spec versions 2 stuff to aid in metacpan indexing
+ - prompted by rt 125178 (needed reindexed in PAUSE), thx for the report TODDR!
+ - change bug tracker to github
+
0.34 2016-01-15 16:07:01
- Add v0.33 tests to the .in file
- simplified Makefile prereqs
diff --git a/MANIFEST b/MANIFEST
index a1d3d9c..31b2da1 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,3 +1,8 @@
+_build/_locales_build_utils.pm
+_build/cldr2locales
+_build/cldr2en
+_build/en2mod
+_build/README
Changes
Makefile.PL
MANIFEST
@@ -868,5 +873,846 @@ lib/Locales/DB/LocaleDisplayPattern.pm
lib/Locales/DB/LocaleDisplayPattern/Tiny.pm
lib/Locales/DB/Docs/PluralForms.pm
lib/Locales/DB/Loadable.pm
+share/misc_info/aa.js
+share/code_to_name/aa.json
+share/datetime/aa.json
+share/functions/aa.js
+share/misc_info/af.js
+share/code_to_name/af.json
+share/datetime/af.json
+share/functions/af.js
+share/misc_info/agq.js
+share/code_to_name/agq.json
+share/datetime/agq.json
+share/functions/agq.js
+share/misc_info/ak.js
+share/code_to_name/ak.json
+share/datetime/ak.json
+share/functions/ak.js
+share/misc_info/am.js
+share/code_to_name/am.json
+share/datetime/am.json
+share/functions/am.js
+share/misc_info/ar.js
+share/code_to_name/ar.json
+share/datetime/ar.json
+share/functions/ar.js
+share/misc_info/as.js
+share/code_to_name/as.json
+share/datetime/as.json
+share/functions/as.js
+share/misc_info/asa.js
+share/code_to_name/asa.json
+share/datetime/asa.json
+share/functions/asa.js
+share/misc_info/az.js
+share/code_to_name/az.json
+share/datetime/az.json
+share/functions/az.js
+share/misc_info/bas.js
+share/code_to_name/bas.json
+share/datetime/bas.json
+share/functions/bas.js
+share/misc_info/be.js
+share/code_to_name/be.json
+share/datetime/be.json
+share/functions/be.js
+share/misc_info/bem.js
+share/code_to_name/bem.json
+share/datetime/bem.json
+share/functions/bem.js
+share/misc_info/bez.js
+share/code_to_name/bez.json
+share/datetime/bez.json
+share/functions/bez.js
+share/misc_info/bg.js
+share/code_to_name/bg.json
+share/datetime/bg.json
+share/functions/bg.js
+share/misc_info/bm.js
+share/code_to_name/bm.json
+share/datetime/bm.json
+share/functions/bm.js
+share/misc_info/bn.js
+share/code_to_name/bn.json
+share/datetime/bn.json
+share/functions/bn.js
+share/misc_info/bo.js
+share/code_to_name/bo.json
+share/datetime/bo.json
+share/functions/bo.js
+share/misc_info/br.js
+share/code_to_name/br.json
+share/datetime/br.json
+share/functions/br.js
+share/misc_info/brx.js
+share/code_to_name/brx.json
+share/datetime/brx.json
+share/functions/brx.js
+share/misc_info/bs.js
+share/code_to_name/bs.json
+share/datetime/bs.json
+share/functions/bs.js
+share/misc_info/byn.js
+share/code_to_name/byn.json
+share/datetime/byn.json
+share/functions/byn.js
+share/misc_info/ca.js
+share/code_to_name/ca.json
+share/datetime/ca.json
+share/functions/ca.js
+share/misc_info/cch.js
+share/code_to_name/cch.json
+share/datetime/cch.json
+share/functions/cch.js
+share/misc_info/cgg.js
+share/code_to_name/cgg.json
+share/datetime/cgg.json
+share/functions/cgg.js
+share/misc_info/chr.js
+share/code_to_name/chr.json
+share/datetime/chr.json
+share/functions/chr.js
+share/misc_info/cs.js
+share/code_to_name/cs.json
+share/datetime/cs.json
+share/functions/cs.js
+share/misc_info/cy.js
+share/code_to_name/cy.json
+share/datetime/cy.json
+share/functions/cy.js
+share/misc_info/da.js
+share/code_to_name/da.json
+share/datetime/da.json
+share/functions/da.js
+share/misc_info/dav.js
+share/code_to_name/dav.json
+share/datetime/dav.json
+share/functions/dav.js
+share/misc_info/de.js
+share/code_to_name/de.json
+share/datetime/de.json
+share/functions/de.js
+share/misc_info/de_at.js
+share/code_to_name/de_at.json
+share/datetime/de_at.json
+share/functions/de_at.js
+share/misc_info/de_ch.js
+share/code_to_name/de_ch.json
+share/datetime/de_ch.json
+share/functions/de_ch.js
+share/misc_info/dje.js
+share/code_to_name/dje.json
+share/datetime/dje.json
+share/functions/dje.js
+share/misc_info/dua.js
+share/code_to_name/dua.json
+share/datetime/dua.json
+share/functions/dua.js
+share/misc_info/dyo.js
+share/code_to_name/dyo.json
+share/datetime/dyo.json
+share/functions/dyo.js
+share/misc_info/dz.js
+share/code_to_name/dz.json
+share/datetime/dz.json
+share/functions/dz.js
+share/misc_info/ebu.js
+share/code_to_name/ebu.json
+share/datetime/ebu.json
+share/functions/ebu.js
+share/misc_info/ee.js
+share/code_to_name/ee.json
+share/datetime/ee.json
+share/functions/ee.js
+share/misc_info/el.js
+share/code_to_name/el.json
+share/datetime/el.json
+share/functions/el.js
+share/misc_info/en.js
+share/code_to_name/en.json
+share/datetime/en.json
+share/functions/en.js
+share/misc_info/en_au.js
+share/code_to_name/en_au.json
+share/datetime/en_au.json
+share/functions/en_au.js
+share/misc_info/en_ca.js
+share/code_to_name/en_ca.json
+share/datetime/en_ca.json
+share/functions/en_ca.js
+share/misc_info/en_gb.js
+share/code_to_name/en_gb.json
+share/datetime/en_gb.json
+share/functions/en_gb.js
+share/misc_info/en_us.js
+share/code_to_name/en_us.json
+share/datetime/en_us.json
+share/functions/en_us.js
+share/misc_info/eo.js
+share/code_to_name/eo.json
+share/datetime/eo.json
+share/functions/eo.js
+share/misc_info/es.js
+share/code_to_name/es.json
+share/datetime/es.json
+share/functions/es.js
+share/misc_info/es_419.js
+share/code_to_name/es_419.json
+share/datetime/es_419.json
+share/functions/es_419.js
+share/misc_info/es_es.js
+share/code_to_name/es_es.json
+share/datetime/es_es.json
+share/functions/es_es.js
+share/misc_info/et.js
+share/code_to_name/et.json
+share/datetime/et.json
+share/functions/et.js
+share/misc_info/eu.js
+share/code_to_name/eu.json
+share/datetime/eu.json
+share/functions/eu.js
+share/misc_info/ewo.js
+share/code_to_name/ewo.json
+share/datetime/ewo.json
+share/functions/ewo.js
+share/misc_info/fa.js
+share/code_to_name/fa.json
+share/datetime/fa.json
+share/functions/fa.js
+share/misc_info/ff.js
+share/code_to_name/ff.json
+share/datetime/ff.json
+share/functions/ff.js
+share/misc_info/fi.js
+share/code_to_name/fi.json
+share/datetime/fi.json
+share/functions/fi.js
+share/misc_info/fil.js
+share/code_to_name/fil.json
+share/datetime/fil.json
+share/functions/fil.js
+share/misc_info/fo.js
+share/code_to_name/fo.json
+share/datetime/fo.json
+share/functions/fo.js
+share/misc_info/fr.js
+share/code_to_name/fr.json
+share/datetime/fr.json
+share/functions/fr.js
+share/misc_info/fr_ca.js
+share/code_to_name/fr_ca.json
+share/datetime/fr_ca.json
+share/functions/fr_ca.js
+share/misc_info/fr_ch.js
+share/code_to_name/fr_ch.json
+share/datetime/fr_ch.json
+share/functions/fr_ch.js
+share/misc_info/fur.js
+share/code_to_name/fur.json
+share/datetime/fur.json
+share/functions/fur.js
+share/misc_info/ga.js
+share/code_to_name/ga.json
+share/datetime/ga.json
+share/functions/ga.js
+share/misc_info/gaa.js
+share/code_to_name/gaa.json
+share/datetime/gaa.json
+share/functions/gaa.js
+share/misc_info/gl.js
+share/code_to_name/gl.json
+share/datetime/gl.json
+share/functions/gl.js
+share/misc_info/gsw.js
+share/code_to_name/gsw.json
+share/datetime/gsw.json
+share/functions/gsw.js
+share/misc_info/gu.js
+share/code_to_name/gu.json
+share/datetime/gu.json
+share/functions/gu.js
+share/misc_info/guz.js
+share/code_to_name/guz.json
+share/datetime/guz.json
+share/functions/guz.js
+share/misc_info/gv.js
+share/code_to_name/gv.json
+share/datetime/gv.json
+share/functions/gv.js
+share/misc_info/ha.js
+share/code_to_name/ha.json
+share/datetime/ha.json
+share/functions/ha.js
+share/misc_info/haw.js
+share/code_to_name/haw.json
+share/datetime/haw.json
+share/functions/haw.js
+share/misc_info/he.js
+share/code_to_name/he.json
+share/datetime/he.json
+share/functions/he.js
+share/misc_info/hi.js
+share/code_to_name/hi.json
+share/datetime/hi.json
+share/functions/hi.js
+share/misc_info/hr.js
+share/code_to_name/hr.json
+share/datetime/hr.json
+share/functions/hr.js
+share/misc_info/hu.js
+share/code_to_name/hu.json
+share/datetime/hu.json
+share/functions/hu.js
+share/misc_info/hy.js
+share/code_to_name/hy.json
+share/datetime/hy.json
+share/functions/hy.js
+share/misc_info/ia.js
+share/code_to_name/ia.json
+share/datetime/ia.json
+share/functions/ia.js
+share/misc_info/id.js
+share/code_to_name/id.json
+share/datetime/id.json
+share/functions/id.js
+share/misc_info/ig.js
+share/code_to_name/ig.json
+share/datetime/ig.json
+share/functions/ig.js
+share/misc_info/ii.js
+share/code_to_name/ii.json
+share/datetime/ii.json
+share/functions/ii.js
+share/misc_info/is.js
+share/code_to_name/is.json
+share/datetime/is.json
+share/functions/is.js
+share/misc_info/it.js
+share/code_to_name/it.json
+share/datetime/it.json
+share/functions/it.js
+share/misc_info/ja.js
+share/code_to_name/ja.json
+share/datetime/ja.json
+share/functions/ja.js
+share/misc_info/jmc.js
+share/code_to_name/jmc.json
+share/datetime/jmc.json
+share/functions/jmc.js
+share/misc_info/ka.js
+share/code_to_name/ka.json
+share/datetime/ka.json
+share/functions/ka.js
+share/misc_info/kab.js
+share/code_to_name/kab.json
+share/datetime/kab.json
+share/functions/kab.js
+share/misc_info/kaj.js
+share/code_to_name/kaj.json
+share/datetime/kaj.json
+share/functions/kaj.js
+share/misc_info/kam.js
+share/code_to_name/kam.json
+share/datetime/kam.json
+share/functions/kam.js
+share/misc_info/kcg.js
+share/code_to_name/kcg.json
+share/datetime/kcg.json
+share/functions/kcg.js
+share/misc_info/kde.js
+share/code_to_name/kde.json
+share/datetime/kde.json
+share/functions/kde.js
+share/misc_info/kea.js
+share/code_to_name/kea.json
+share/datetime/kea.json
+share/functions/kea.js
+share/misc_info/khq.js
+share/code_to_name/khq.json
+share/datetime/khq.json
+share/functions/khq.js
+share/misc_info/ki.js
+share/code_to_name/ki.json
+share/datetime/ki.json
+share/functions/ki.js
+share/misc_info/kk.js
+share/code_to_name/kk.json
+share/datetime/kk.json
+share/functions/kk.js
+share/misc_info/kl.js
+share/code_to_name/kl.json
+share/datetime/kl.json
+share/functions/kl.js
+share/misc_info/kln.js
+share/code_to_name/kln.json
+share/datetime/kln.json
+share/functions/kln.js
+share/misc_info/km.js
+share/code_to_name/km.json
+share/datetime/km.json
+share/functions/km.js
+share/misc_info/kn.js
+share/code_to_name/kn.json
+share/datetime/kn.json
+share/functions/kn.js
+share/misc_info/ko.js
+share/code_to_name/ko.json
+share/datetime/ko.json
+share/functions/ko.js
+share/misc_info/kok.js
+share/code_to_name/kok.json
+share/datetime/kok.json
+share/functions/kok.js
+share/misc_info/ksb.js
+share/code_to_name/ksb.json
+share/datetime/ksb.json
+share/functions/ksb.js
+share/misc_info/ksf.js
+share/code_to_name/ksf.json
+share/datetime/ksf.json
+share/functions/ksf.js
+share/misc_info/ksh.js
+share/code_to_name/ksh.json
+share/datetime/ksh.json
+share/functions/ksh.js
+share/misc_info/ku.js
+share/code_to_name/ku.json
+share/datetime/ku.json
+share/functions/ku.js
+share/misc_info/kw.js
+share/code_to_name/kw.json
+share/datetime/kw.json
+share/functions/kw.js
+share/misc_info/ky.js
+share/code_to_name/ky.json
+share/datetime/ky.json
+share/functions/ky.js
+share/misc_info/lag.js
+share/code_to_name/lag.json
+share/datetime/lag.json
+share/functions/lag.js
+share/misc_info/lg.js
+share/code_to_name/lg.json
+share/datetime/lg.json
+share/functions/lg.js
+share/misc_info/ln.js
+share/code_to_name/ln.json
+share/datetime/ln.json
+share/functions/ln.js
+share/misc_info/lo.js
+share/code_to_name/lo.json
+share/datetime/lo.json
+share/functions/lo.js
+share/misc_info/lt.js
+share/code_to_name/lt.json
+share/datetime/lt.json
+share/functions/lt.js
+share/misc_info/lu.js
+share/code_to_name/lu.json
+share/datetime/lu.json
+share/functions/lu.js
+share/misc_info/luo.js
+share/code_to_name/luo.json
+share/datetime/luo.json
+share/functions/luo.js
+share/misc_info/luy.js
+share/code_to_name/luy.json
+share/datetime/luy.json
+share/functions/luy.js
+share/misc_info/lv.js
+share/code_to_name/lv.json
+share/datetime/lv.json
+share/functions/lv.js
+share/misc_info/mas.js
+share/code_to_name/mas.json
+share/datetime/mas.json
+share/functions/mas.js
+share/misc_info/mer.js
+share/code_to_name/mer.json
+share/datetime/mer.json
+share/functions/mer.js
+share/misc_info/mfe.js
+share/code_to_name/mfe.json
+share/datetime/mfe.json
+share/functions/mfe.js
+share/misc_info/mg.js
+share/code_to_name/mg.json
+share/datetime/mg.json
+share/functions/mg.js
+share/misc_info/mgh.js
+share/code_to_name/mgh.json
+share/datetime/mgh.json
+share/functions/mgh.js
+share/misc_info/mk.js
+share/code_to_name/mk.json
+share/datetime/mk.json
+share/functions/mk.js
+share/misc_info/ml.js
+share/code_to_name/ml.json
+share/datetime/ml.json
+share/functions/ml.js
+share/misc_info/mn.js
+share/code_to_name/mn.json
+share/datetime/mn.json
+share/functions/mn.js
+share/misc_info/mo.js
+share/code_to_name/mo.json
+share/datetime/mo.json
+share/functions/mo.js
+share/misc_info/mr.js
+share/code_to_name/mr.json
+share/datetime/mr.json
+share/functions/mr.js
+share/misc_info/ms.js
+share/code_to_name/ms.json
+share/datetime/ms.json
+share/functions/ms.js
+share/misc_info/mt.js
+share/code_to_name/mt.json
+share/datetime/mt.json
+share/functions/mt.js
+share/misc_info/mua.js
+share/code_to_name/mua.json
+share/datetime/mua.json
+share/functions/mua.js
+share/misc_info/my.js
+share/code_to_name/my.json
+share/datetime/my.json
+share/functions/my.js
+share/misc_info/naq.js
+share/code_to_name/naq.json
+share/datetime/naq.json
+share/functions/naq.js
+share/misc_info/nb.js
+share/code_to_name/nb.json
+share/datetime/nb.json
+share/functions/nb.js
+share/misc_info/nd.js
+share/code_to_name/nd.json
+share/datetime/nd.json
+share/functions/nd.js
+share/misc_info/nds.js
+share/code_to_name/nds.json
+share/datetime/nds.json
+share/functions/nds.js
+share/misc_info/ne.js
+share/code_to_name/ne.json
+share/datetime/ne.json
+share/functions/ne.js
+share/misc_info/nl.js
+share/code_to_name/nl.json
+share/datetime/nl.json
+share/functions/nl.js
+share/misc_info/nl_be.js
+share/code_to_name/nl_be.json
+share/datetime/nl_be.json
+share/functions/nl_be.js
+share/misc_info/nmg.js
+share/code_to_name/nmg.json
+share/datetime/nmg.json
+share/functions/nmg.js
+share/misc_info/nn.js
+share/code_to_name/nn.json
+share/datetime/nn.json
+share/functions/nn.js
+share/misc_info/no.js
+share/code_to_name/no.json
+share/datetime/no.json
+share/functions/no.js
+share/misc_info/nr.js
+share/code_to_name/nr.json
+share/datetime/nr.json
+share/functions/nr.js
+share/misc_info/nso.js
+share/code_to_name/nso.json
+share/datetime/nso.json
+share/functions/nso.js
+share/misc_info/nus.js
+share/code_to_name/nus.json
+share/datetime/nus.json
+share/functions/nus.js
+share/misc_info/nyn.js
+share/code_to_name/nyn.json
+share/datetime/nyn.json
+share/functions/nyn.js
+share/misc_info/oc.js
+share/code_to_name/oc.json
+share/datetime/oc.json
+share/functions/oc.js
+share/misc_info/om.js
+share/code_to_name/om.json
+share/datetime/om.json
+share/functions/om.js
+share/misc_info/or.js
+share/code_to_name/or.json
+share/datetime/or.json
+share/functions/or.js
+share/misc_info/pa.js
+share/code_to_name/pa.json
+share/datetime/pa.json
+share/functions/pa.js
+share/misc_info/pl.js
+share/code_to_name/pl.json
+share/datetime/pl.json
+share/functions/pl.js
+share/misc_info/ps.js
+share/code_to_name/ps.json
+share/datetime/ps.json
+share/functions/ps.js
+share/misc_info/pt.js
+share/code_to_name/pt.json
+share/datetime/pt.json
+share/functions/pt.js
+share/misc_info/pt_br.js
+share/code_to_name/pt_br.json
+share/datetime/pt_br.json
+share/functions/pt_br.js
+share/misc_info/pt_pt.js
+share/code_to_name/pt_pt.json
+share/datetime/pt_pt.json
+share/functions/pt_pt.js
+share/misc_info/rm.js
+share/code_to_name/rm.json
+share/datetime/rm.json
+share/functions/rm.js
+share/misc_info/rn.js
+share/code_to_name/rn.json
+share/datetime/rn.json
+share/functions/rn.js
+share/misc_info/ro.js
+share/code_to_name/ro.json
+share/datetime/ro.json
+share/functions/ro.js
+share/misc_info/rof.js
+share/code_to_name/rof.json
+share/datetime/rof.json
+share/functions/rof.js
+share/misc_info/ru.js
+share/code_to_name/ru.json
+share/datetime/ru.json
+share/functions/ru.js
+share/misc_info/rw.js
+share/code_to_name/rw.json
+share/datetime/rw.json
+share/functions/rw.js
+share/misc_info/rwk.js
+share/code_to_name/rwk.json
+share/datetime/rwk.json
+share/functions/rwk.js
+share/misc_info/sah.js
+share/code_to_name/sah.json
+share/datetime/sah.json
+share/functions/sah.js
+share/misc_info/saq.js
+share/code_to_name/saq.json
+share/datetime/saq.json
+share/functions/saq.js
+share/misc_info/sbp.js
+share/code_to_name/sbp.json
+share/datetime/sbp.json
+share/functions/sbp.js
+share/misc_info/se.js
+share/code_to_name/se.json
+share/datetime/se.json
+share/functions/se.js
+share/misc_info/seh.js
+share/code_to_name/seh.json
+share/datetime/seh.json
+share/functions/seh.js
+share/misc_info/ses.js
+share/code_to_name/ses.json
+share/datetime/ses.json
+share/functions/ses.js
+share/misc_info/sg.js
+share/code_to_name/sg.json
+share/datetime/sg.json
+share/functions/sg.js
+share/misc_info/sh.js
+share/code_to_name/sh.json
+share/datetime/sh.json
+share/functions/sh.js
+share/misc_info/shi.js
+share/code_to_name/shi.json
+share/datetime/shi.json
+share/functions/shi.js
+share/misc_info/si.js
+share/code_to_name/si.json
+share/datetime/si.json
+share/functions/si.js
+share/misc_info/sid.js
+share/code_to_name/sid.json
+share/datetime/sid.json
+share/functions/sid.js
+share/misc_info/sk.js
+share/code_to_name/sk.json
+share/datetime/sk.json
+share/functions/sk.js
+share/misc_info/sl.js
+share/code_to_name/sl.json
+share/datetime/sl.json
+share/functions/sl.js
+share/misc_info/sn.js
+share/code_to_name/sn.json
+share/datetime/sn.json
+share/functions/sn.js
+share/misc_info/so.js
+share/code_to_name/so.json
+share/datetime/so.json
+share/functions/so.js
+share/misc_info/sq.js
+share/code_to_name/sq.json
+share/datetime/sq.json
+share/functions/sq.js
+share/misc_info/sr.js
+share/code_to_name/sr.json
+share/datetime/sr.json
+share/functions/sr.js
+share/misc_info/ss.js
+share/code_to_name/ss.json
+share/datetime/ss.json
+share/functions/ss.js
+share/misc_info/ssy.js
+share/code_to_name/ssy.json
+share/datetime/ssy.json
+share/functions/ssy.js
+share/misc_info/st.js
+share/code_to_name/st.json
+share/datetime/st.json
+share/functions/st.js
+share/misc_info/sv.js
+share/code_to_name/sv.json
+share/datetime/sv.json
+share/functions/sv.js
+share/misc_info/sw.js
+share/code_to_name/sw.json
+share/datetime/sw.json
+share/functions/sw.js
+share/misc_info/swc.js
+share/code_to_name/swc.json
+share/datetime/swc.json
+share/functions/swc.js
+share/misc_info/ta.js
+share/code_to_name/ta.json
+share/datetime/ta.json
+share/functions/ta.js
+share/misc_info/te.js
+share/code_to_name/te.json
+share/datetime/te.json
+share/functions/te.js
+share/misc_info/teo.js
+share/code_to_name/teo.json
+share/datetime/teo.json
+share/functions/teo.js
+share/misc_info/tg.js
+share/code_to_name/tg.json
+share/datetime/tg.json
+share/functions/tg.js
+share/misc_info/th.js
+share/code_to_name/th.json
+share/datetime/th.json
+share/functions/th.js
+share/misc_info/ti.js
+share/code_to_name/ti.json
+share/datetime/ti.json
+share/functions/ti.js
+share/misc_info/tig.js
+share/code_to_name/tig.json
+share/datetime/tig.json
+share/functions/tig.js
+share/misc_info/tl.js
+share/code_to_name/tl.json
+share/datetime/tl.json
+share/functions/tl.js
+share/misc_info/tn.js
+share/code_to_name/tn.json
+share/datetime/tn.json
+share/functions/tn.js
+share/misc_info/to.js
+share/code_to_name/to.json
+share/datetime/to.json
+share/functions/to.js
+share/misc_info/tr.js
+share/code_to_name/tr.json
+share/datetime/tr.json
+share/functions/tr.js
+share/misc_info/trv.js
+share/code_to_name/trv.json
+share/datetime/trv.json
+share/functions/trv.js
+share/misc_info/ts.js
+share/code_to_name/ts.json
+share/datetime/ts.json
+share/functions/ts.js
+share/misc_info/twq.js
+share/code_to_name/twq.json
+share/datetime/twq.json
+share/functions/twq.js
+share/misc_info/tzm.js
+share/code_to_name/tzm.json
+share/datetime/tzm.json
+share/functions/tzm.js
+share/misc_info/uk.js
+share/code_to_name/uk.json
+share/datetime/uk.json
+share/functions/uk.js
+share/misc_info/ur.js
+share/code_to_name/ur.json
+share/datetime/ur.json
+share/functions/ur.js
+share/misc_info/uz.js
+share/code_to_name/uz.json
+share/datetime/uz.json
+share/functions/uz.js
+share/misc_info/vai.js
+share/code_to_name/vai.json
+share/datetime/vai.json
+share/functions/vai.js
+share/misc_info/ve.js
+share/code_to_name/ve.json
+share/datetime/ve.json
+share/functions/ve.js
+share/misc_info/vi.js
+share/code_to_name/vi.json
+share/datetime/vi.json
+share/functions/vi.js
+share/misc_info/vun.js
+share/code_to_name/vun.json
+share/datetime/vun.json
+share/functions/vun.js
+share/misc_info/wae.js
+share/code_to_name/wae.json
+share/datetime/wae.json
+share/functions/wae.js
+share/misc_info/wal.js
+share/code_to_name/wal.json
+share/datetime/wal.json
+share/functions/wal.js
+share/misc_info/xh.js
+share/code_to_name/xh.json
+share/datetime/xh.json
+share/functions/xh.js
+share/misc_info/xog.js
+share/code_to_name/xog.json
+share/datetime/xog.json
+share/functions/xog.js
+share/misc_info/yav.js
+share/code_to_name/yav.json
+share/datetime/yav.json
+share/functions/yav.js
+share/misc_info/yo.js
+share/code_to_name/yo.json
+share/datetime/yo.json
+share/functions/yo.js
+share/misc_info/zh.js
+share/code_to_name/zh.json
+share/datetime/zh.json
+share/functions/zh.js
+share/misc_info/zu.js
+share/code_to_name/zu.json
+share/datetime/zu.json
+share/functions/zu.js
+share/db/loadable.json
META.yml Module YAML meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
diff --git a/META.json b/META.json
index 77b26c2..d833817 100644
--- a/META.json
+++ b/META.json
@@ -3,14 +3,14 @@
"author" : [
"Daniel Muey <http://drmuey.com/cpan_contact.pl>"
],
- "dynamic_config" : 1,
- "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.150001",
+ "dynamic_config" : 0,
+ "generated_by" : "ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter version 2.150010",
"license" : [
"unknown"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
- "version" : "2"
+ "version" : 2
},
"name" : "Locales",
"no_index" : {
@@ -45,5 +45,16 @@
}
},
"release_status" : "stable",
- "version" : "0.34"
+ "resources" : {
+ "bugtracker" : {
+ "web" : "https://github.com/drmuey/p5-Locales/issues"
+ },
+ "repository" : {
+ "type" : "git",
+ "url" : "https://github.com/drmuey/p5-Locales.git",
+ "web" : "https://github.com/drmuey/p5-Locales"
+ }
+ },
+ "version" : "0.34",
+ "x_serialization_backend" : "JSON::PP version 4.07"
}
diff --git a/META.yml b/META.yml
index f21d719..4ac85f0 100644
--- a/META.yml
+++ b/META.yml
@@ -9,8 +9,8 @@ build_requires:
Test::More: '0'
configure_requires:
ExtUtils::MakeMaker: '6.56'
-dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.150001'
+dynamic_config: 0
+generated_by: 'ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter version 2.150010'
license: unknown
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -27,4 +27,8 @@ requires:
String::UnicodeUTF8: '0'
Test::Carp: '0'
Test::More: '0'
+resources:
+ bugtracker: https://github.com/drmuey/p5-Locales/issues
+ repository: https://github.com/drmuey/p5-Locales.git
version: '0.34'
+x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff --git a/Makefile.PL b/Makefile.PL
index 31fbb62..02539ee 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -25,6 +25,20 @@ WriteMakefile(
CONFIGURE_REQUIRES => {
'ExtUtils::MakeMaker' => 6.56,
},
- dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
- clean => { FILES => 'Locales-*' },
+ dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
+ clean => { FILES => 'Locales-*' },
+ META_ADD => {
+ 'meta-spec' => { version => 2 },
+ dynamic_config => 0,
+ resources => {
+ repository => {
+ url => 'https://github.com/drmuey/p5-Locales.git',
+ web => 'https://github.com/drmuey/p5-Locales',
+ type => 'git',
+ },
+ bugtracker => {
+ web => 'https://github.com/drmuey/p5-Locales/issues',
+ },
+ },
+ },
);
diff --git a/_build/README b/_build/README
new file mode 100644
index 0000000..07b4377
--- /dev/null
+++ b/_build/README
@@ -0,0 +1,27 @@
+How to update:
+
+0) get latest CLDR from http://cldr.unicode.org/index/downloads
+
+1) update $Locales::CLDR_VERSION && $Locales::VERSION
+
+2) build modules out of CLDR, something like this:
+
+ Note: If the DB mods are NOT changing you'll have to update "my $v_offset" in _locales_build_utils.pm && perl -pi -e 's{0\.25}{0.26}g;' t/042.*
+
+ ./_build/cldr2locales ../Downloads/
+
+../Downloads/ == path to downloaded and extracted CLDR core (should contain 'common/main' dir)
+
+3) do any other changes
+
+4) tidy it all (rt 69971)
+
+ perltidy -b `find lib/Locales/DB -name '*.pm'`
+ perltidy -b lib/Locales.pm
+ rm `find . -name '*.bak'`
+
+5) perl Makefile.PL && make && make test
+
+6) RELEASE_TESTING=1 make test
+
+7) ... make dist && sudo make install
\ No newline at end of file
diff --git a/_build/_locales_build_utils.pm b/_build/_locales_build_utils.pm
new file mode 100644
index 0000000..3f1acf4
--- /dev/null
+++ b/_build/_locales_build_utils.pm
@@ -0,0 +1,1427 @@
+package _locales_build_utils;
+
+use Cwd;
+use XML::Simple;
+use XML::Twig;
+use File::Path::Tiny;
+use lib Cwd::realpath('lib');
+use Locales;
+use File::Slurp;
+use Encode (); # to be stringified properly from hash value bug: s{\|\|\s*(\$fallback_lang_misc_info\-\>\S*)\,}{|| Encode::decode_utf8($1),}
+use String::Unquotemeta;
+use JSON::Syck;
+use JavaScript::Minifier::XS;
+
+#### this ugliness will be spruced up when we go to CLDR-via-JSON in rt 69340 (no XML voo doo and we can move to TT for mod building) ##
+
+# datetime.json
+our $tripped;
+use Test::Carp sub { $tripped = 1 if $_[0]; };
+use DateTime::Locale;
+use Class::Inspector;
+my $en_dt_loc = DateTime::Locale->load('en');
+my @dt_methods;
+for my $meth ( @{ Class::Inspector->methods( ref($en_dt_loc), "public" ) } ) {
+ next if $meth eq 'new' || $meth eq 'carp' || $meth eq 'format_for' || $meth eq 'validate_pos';
+ next if $meth =~ m/^(:?set_|STORABLE_)/;
+
+ *DateTime::Locale::Base::carp = sub { Carp::carp( $_[0] ) };
+ local $tripped = 0;
+ Test::Carp::does_carp_that_matches(
+ sub {
+ eval { $en_dt_loc->$meth() };
+ },
+ qr/The $meth method in DateTime::Locale::Base has been deprecated/
+ );
+ next if $tripped;
+
+ push @dt_methods, $meth;
+}
+my @dt_available_formats = $en_dt_loc->available_formats();
+
+# /datetime.json
+
+use Hash::Merge;
+Hash::Merge::specify_behavior(
+ {
+ 'SCALAR' => {
+ 'SCALAR' => sub { !defined $_[0] ? $_[1] : $_[0] },
+ 'ARRAY' => sub { !defined $_[0] ? $_[1] : $_[0] },
+ 'HASH' => sub { !defined $_[0] ? $_[1] : $_[0] },
+ },
+ 'ARRAY' => {
+ 'SCALAR' => sub { defined $_[0] ? $_[0] : [ @{ $_[0] }, $_[1] ] },
+ 'ARRAY' => sub { defined $_[0] ? $_[0] : [ @{ $_[0] }, @{ $_[1] } ] },
+ 'HASH' => sub { defined $_[0] ? $_[0] : [ @{ $_[0] }, values %{ $_[1] } ] },
+ },
+ 'HASH' => {
+ 'SCALAR' => sub { $_[0] },
+ 'ARRAY' => sub { $_[0] },
+ 'HASH' => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
+ },
+ },
+ "left undef/missing"
+);
+
+sub merge_hash {
+ goto &Hash::Merge::merge;
+}
+use Data::Dumper;
+$Data::Dumper::Terse = 1;
+$Data::Dumper::Sortkeys = 1;
+$Data::Dumper::Useqq = 1;
+{
+ no warnings 'redefine';
+
+ sub Data::Dumper::qquote {
+ my $s = shift;
+ my $q = quotemeta($s);
+ return $s ne $q ? qq{"$q"} : qq{'$s'};
+ }
+}
+
+my $v_offset = '0.24';
+my $mod_version = $Locales::VERSION - $v_offset;
+my $cldr_version = $Locales::cldr_version;
+my $cldr_db_path;
+my $locales_db;
+my $manifest;
+our $plural_forms;
+
+sub init_paths_from_argv {
+ die "no CLDR path given" if !-d "$ARGV[0]/common/main";
+ $cldr_db_path = Cwd::realpath( $ARGV[0] ) || die "need path to CLDR";
+ $locales_db = Cwd::realpath( $SARGV[1] || 'lib/Locales/DB' );
+ $manifest = Cwd::realpath( $SARGV[2] || 'MANIFEST.build' );
+
+ my $plural_forms_xml = XMLin( "$ARGV[0]/common/supplemental/plurals.xml", ForceArray => 1 ); # ,'KeyAttr' => {'pluralRules' => '+locales' });
+ for my $plural ( @{ $plural_forms_xml->{'plurals'}[0]{'pluralRules'} } ) {
+ for my $loc ( split( /\s+/, $plural->{'locales'} ) ) {
+ $plural_forms->{$loc} = { map { $_->{'count'} => $_->{'content'} } @{ $plural->{'pluralRule'} } };
+ if ( !keys %{ $plural_forms->{$loc} } ) {
+ $plural_forms->{$loc} = undef();
+ }
+ }
+ }
+
+ # print Dumper($plural_forms);die; # _xml->{'plurals'}[0]{'pluralRules'});die;
+
+ return ( $cldr_db_path, $locales_db, $manifest );
+}
+
+sub get_xml_file_for {
+ my ( $tag, $quiet ) = @_;
+ my $xml_file = "$cldr_db_path/common/main/$tag.xml";
+ if ( !-e $xml_file ) {
+ warn "\t1) No $xml_file ...\n" if !$quiet;
+ my $tag_copy = $tag;
+ $tag_copy =~ s{_(\w+)$}{_\U$1\E};
+ $xml_file = "$cldr_db_path/common/main/$tag_copy.xml";
+ if ( !-e $xml_file ) {
+ warn "\t2) No $xml_file ...\n" if !$quiet;
+ $tag_copy =~ tr/a-z/A-Z/;
+ $xml_file = "$cldr_db_path/common/main/$tag_copy.xml";
+ if ( !-e $xml_file ) {
+ warn "\t3) No $xml_file ...\n" if !$quiet;
+ return;
+ }
+ }
+ }
+ return $xml_file;
+
+}
+
+sub get_target_structs_from_cldr_for_tag {
+ my ( $tag, $fallback_lang_code_to_name, $fallback_terr_code_to_name, $fallback_lang_misc_info ) = @_;
+
+ # if ( $tag eq 'pt_br' ) { print Dumper( [ 'get_target_structs_from_cldr_for_tag', $fallback_lang_misc_info ] ) }
+ my $xml_file = get_xml_file_for($tag);
+ return if !-e $xml_file;
+
+ print "Loading $tag XML from $xml_file...\n";
+
+ # my $raw_struct = XMLin($xml_file, 'KeyAttr' => 'type');
+ my $raw_struct = XML::Twig->new()->parsefile($xml_file)->simplify(
+ 'keyattr' => {
+ 'codePattern' => '+type',
+ 'listPatternPart' => '+type',
+ 'characters' => '+type',
+ 'ellipsis' => '+type',
+ 'territory' => '+type',
+ 'language' => '+type',
+ }
+ );
+
+ my ( $lang_code_to_name, $lang_name_to_code, $lang_misc_info, $terr_code_to_name, $terr_name_to_code ) = ( {}, {}, {}, {}, {} );
+
+ #### Territories ####
+ for my $trr ( keys %{ $raw_struct->{'localeDisplayNames'}{'territories'}{'territory'} } ) {
+
+ # Do not skip ISO 3166-1-numeric (e.g. 419, as in es_419)
+ # next if $trr =~ m/^\d+$/;
+
+ my $short = $trr;
+ $short =~ tr/A-Z/a-z/;
+
+ $terr_code_to_name->{$short} = $raw_struct->{'localeDisplayNames'}{'territories'}{'territory'}{$trr}{'content'};
+ $terr_name_to_code->{ Locales::normalize_for_key_lookup( $raw_struct->{'localeDisplayNames'}{'territories'}{'territory'}{$trr}{'content'} ) } = $short;
+ }
+
+ if ($fallback_terr_code_to_name) {
+ for my $fb_trr ( keys %{$fallback_terr_code_to_name} ) {
+ if ( !exists $terr_code_to_name->{$fb_trr} ) {
+ $terr_code_to_name->{$fb_trr} = $fallback_terr_code_to_name->{$fb_trr};
+ $terr_name_to_code->{ Locales::normalize_for_key_lookup( $fallback_terr_code_to_name->{$fb_trr} ) } = $fb_trr;
+ }
+ }
+ }
+ #### /Territories ####
+
+ #### Languages ####
+ my $fallback = undef; # or [] ?
+ if ( exists $raw_struct->{'fallback'} ) {
+ $fallback = [];
+ if ( my $type = ref( $raw_struct->{'fallback'} ) ) {
+ if ( $type eq 'ARRAY' ) {
+ for my $fb ( @{ $raw_struct->{'fallback'} } ) {
+ my $thing = ref($fb) ? $fb->{'content'} : $fb;
+ next if !defined $thing;
+ push @{$fallback}, map { Locales::normalize_tag("$_") } split( /\s+/, $thing );
+ }
+ }
+ elsif ( $type eq 'HASH' ) {
+ if ( $raw_struct->{'fallback'}{'content'} ) {
+ push @{$fallback}, map { Locales::normalize_tag("$_") } split( /\s+/, $raw_struct->{'fallback'}{'content'} );
+ }
+ }
+ }
+ else {
+ if ( $raw_struct->{'fallback'} ) {
+ push @{$fallback}, map { Locales::normalize_tag("$_") } split( /\s+/, $raw_struct->{'fallback'} );
+ }
+ }
+ }
+ elsif ( exists $fallback_lang_misc_info->{'fallback'} ) {
+ $fallback = [];
+ if ( my $type = ref( $fallback_lang_misc_info->{'fallback'} ) ) {
+ if ( $type eq 'ARRAY' ) {
+ for my $fb ( @{ $fallback_lang_misc_info->{'fallback'} } ) {
+ my $thing = ref($fb) ? $fb->{'content'} : $fb;
+ next if !defined $thing;
+ push @{$fallback}, map { Locales::normalize_tag("$_") } split( /\s+/, $thing );
+ }
+ }
+ elsif ( $type eq 'HASH' ) {
+ if ( $fallback_lang_misc_info->{'fallback'}{'content'} ) {
+ push @{$fallback}, map { Locales::normalize_tag("$_") } split( /\s+/, $fallback_lang_misc_info->{'fallback'}{'content'} );
+ }
+ }
+ }
+ else {
+ if ( $fallback_lang_misc_info->{'fallback'} ) {
+ push @{$fallback}, map { Locales::normalize_tag("$_") } split( /\s+/, $fallback_lang_misc_info->{'fallback'} );
+ }
+ }
+ }
+
+ my $symbols_index;
+ if ( ref( $raw_struct->{'numbers'}{'symbols'} ) eq 'ARRAY' ) {
+ my $default_numbersystem = $raw_struct->{'numbers'}{'defaultNumberingSystem'} || $raw_struct->{'numbers'}{'defaultNumberingSystem'} || 'latn';
+ if ( ref($default_numbersystem) eq 'HASH' ) {
+ $default_numbersystem = $default_numbersystem->{'content'};
+ }
+
+ my $idx = -1;
+ for my $item ( @{ $raw_struct->{'numbers'}{'symbols'} } ) {
+ $idx++;
+
+ if ( ref($item) eq 'HASH' && $item->{'numberSystem'} eq $default_numbersystem ) {
+ $symbols_index = $idx;
+ last;
+ }
+ }
+ }
+
+ my $_decimal_format_group =
+ defined $symbols_index
+ ? (
+ ref $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'group'} eq 'HASH' ? $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'group'}{'content'}
+ : ref $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'group'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'group'}->[0]
+ : $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'group'}
+ )
+ : (
+ ref $raw_struct->{'numbers'}{'symbols'}{'group'} eq 'HASH' ? $raw_struct->{'numbers'}{'symbols'}{'group'}{'content'}
+ : ref $raw_struct->{'numbers'}{'symbols'}{'group'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'symbols'}{'group'}->[0]
+ : $raw_struct->{'numbers'}{'symbols'}{'group'}
+ );
+ if ( ref($_decimal_format_group) eq 'HASH' ) {
+ $_decimal_format_group = $_decimal_format_group->{'content'};
+ }
+
+ my $_decimal_format_decimal = defined $symbols_index
+ ? (
+ ref $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'decimal'} eq 'HASH' ? $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'decimal'}{'content'}
+ : ref $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'decimal'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'decimal'}->[0]
+ : $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'decimal'}
+
+ )
+ : (
+ ref $raw_struct->{'numbers'}{'symbols'}{'decimal'} eq 'HASH' ? $raw_struct->{'numbers'}{'symbols'}{'decimal'}{'content'}
+ : ref $raw_struct->{'numbers'}{'symbols'}{'decimal'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'symbols'}{'decimal'}->[0]
+ : $raw_struct->{'numbers'}{'symbols'}{'decimal'}
+ );
+ if ( ref($_decimal_format_decimal) eq 'HASH' ) {
+ $_decimal_format_decimal = $_decimal_format_decimal->{'content'};
+ }
+
+ # only fallback if *both* will match
+ if ( !$_decimal_format_group && !$_decimal_format_decimal ) {
+ $_decimal_format_group = $fallback_lang_misc_info->{'cldr_formats'}{'_decimal_format_group'};
+ $_decimal_format_decimal = $fallback_lang_misc_info->{'cldr_formats'}{'_decimal_format_decimal'};
+ }
+
+ # if we are missing one use both it's parent's data if possible
+ if ( !$_decimal_format_group || !$_decimal_format_decimal ) {
+ my ( $l, $t ) = Locales::split_tag($tag);
+ if ($t) {
+ if ( my $parent = Locales->new($l) ) {
+ no strict 'refs';
+ $_decimal_format_group = ${"Locales::DB::Language::${l}::misc_info"}{'cldr_formats'}->{'_decimal_format_group'};
+ $_decimal_format_decimal = ${"Locales::DB::Language::${l}::misc_info"}{'cldr_formats'}->{'_decimal_format_decimal'};
+ }
+ }
+ }
+
+ if ( !$_decimal_format_group || !$_decimal_format_decimal ) {
+
+ # not much we can (accuratly) do, I am open to suggestions :)
+ warn "'$tag' is missing one or both decimal format options: _decimal_format_group ($_decimal_format_group) or _decimal_format_decimal ($_decimal_format_decimal) ...";
+ if ( $_decimal_format_group eq ',' ) {
+ $_decimal_format_decimal = '.';
+ }
+ elsif ( $_decimal_format_group eq '.' ) {
+ $_decimal_format_decimal = ',';
+ }
+ elsif ( $_decimal_format_decimal eq ',' ) {
+ $_decimal_format_group = '.';
+ }
+ elsif ( $_decimal_format_decimal eq '.' ) {
+ $_decimal_format_group = ',';
+ }
+
+ # TODO: fallback to values in its numberSystem (e.g. <symbols numberSystem="latn">) (only trips up a few as of CLDR 2.0)
+ elsif ( $tag eq 'ak' || $tag eq 'mfe' || $tag eq 'ses' || $tag eq 'khq' || $tag eq 'wal' ) {
+ $_decimal_format_decimal = '.';
+ }
+
+ else {
+ warn "\tCould not make worst-case-best-effort defualt from the curretn value.";
+ }
+ }
+
+ my $_percent_format_percent = (
+ defined $symbols_index
+ ? (
+ ref $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'percentSign'} eq 'HASH' ? $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'percentSign'}{'content'}
+ : ref $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'percentSign'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'percentSign'}->[0]
+ : $raw_struct->{'numbers'}{'symbols'}[$symbols_index]{'percentSign'}
+ )
+ : (
+ ref $raw_struct->{'numbers'}{'symbols'}{'percentSign'} eq 'HASH' ? $raw_struct->{'numbers'}{'symbols'}{'percentSign'}{'content'}
+ : ref $raw_struct->{'numbers'}{'symbols'}{'percentSign'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'symbols'}{'percentSign'}->[0]
+ : $raw_struct->{'numbers'}{'symbols'}{'percentSign'}
+ )
+ )
+ || $fallback_lang_misc_info->{'cldr_formats'}{'_percent_format_percent'};
+ if ( !$_percent_format_percent ) {
+ my ( $l, $t ) = Locales::split_tag($tag);
+ if ($t) {
+ if ( my $parent = Locales->new($l) ) {
+ no strict 'refs';
+ $_percent_format_percent = ${"Locales::DB::Language::${l}::misc_info"}{'cldr_formats'}->{'_percent_format_percent'};
+ }
+ }
+ }
+
+ # $fallback_lang_misc_info->{'cldr_formats'}{'delimiters'} ||= {
+ # map {
+ # my $norm = $_;
+ # $norm = lcfirst($norm);
+ # $norm =~ s/([A-Z])/_\L$1\E/g;
+ # ($norm => $raw_struct->{'delimiters'}{$_})
+ # } keys %{ $raw_struct->{'delimiters'} }
+ # };
+
+ # if ( $tag eq 'pt_br' ) { use Data::Dumper; print Dumper( $tag, $fallback_lang_misc_info ) }
+
+ # ick
+ if ( ref( $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'} ) eq 'HASH' ) {
+ if ( $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}{'type'} eq 'short' ) {
+ delete $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'};
+ }
+ }
+ elsif ( ref( $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'} ) eq 'ARRAY' ) {
+ if ( $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}[0]{'type'} eq 'short' ) {
+ shift @{ $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'} };
+ }
+ }
+
+ my $plural_form_entry = $plural_forms->{$tag};
+ if ( !$plural_form_entry ) {
+ my ($parent_tag) = Locales::split_tag($tag);
+ if ( $parent_tag ne $tag && exists $plural_forms->{$parent_tag} ) {
+ $plural_form_entry = $plural_forms->{$parent_tag};
+ }
+ else {
+ for my $fb ( @{$fallback} ) {
+ if ( exists $plural_forms->{$fb} && ref( $plural_forms->{$fb} ) ) {
+ $plural_form_entry = $plural_forms->{$fb};
+ last;
+ }
+ }
+ }
+ }
+
+ # DO NOT DO THIS: $plural_form_entry ||= $plural_forms->{'en'};
+
+ $lang_misc_info = {
+ 'fallback' => $fallback,
+ 'cldr_formats' => {
+ 'decimal' => (
+ ref( $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'} ) eq 'ARRAY'
+ ? (
+ ref $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}[0]{'decimalFormat'}{'pattern'} eq 'HASH' ? $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}[0]{'decimalFormat'}{'pattern'}{'content'}
+ : ref $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}[0]{'decimalFormat'}{'pattern'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}[0]{'decimalFormat'}{'pattern'}->[0]
+ : $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}[0]{'decimalFormat'}{'pattern'}
+
+ )
+ : (
+ ref $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}{'decimalFormat'}{'pattern'} eq 'HASH' ? $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}{'decimalFormat'}{'pattern'}{'content'}
+ : ref $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}{'decimalFormat'}{'pattern'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}{'decimalFormat'}{'pattern'}->[0]
+ : $raw_struct->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}{'decimalFormat'}{'pattern'}
+ )
+ )
+ || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'decimal'} ),
+ '_decimal_format_group' => $_decimal_format_group,
+ '_decimal_format_decimal' => $_decimal_format_decimal,
+ 'percent' => (
+ ref $raw_struct->{'numbers'}{'percentFormats'}{'percentFormatLength'}{'percentFormat'}{'pattern'} eq 'HASH' ? $raw_struct->{'numbers'}{'percentFormats'}{'percentFormatLength'}{'percentFormat'}{'pattern'}{'content'}
+ : ref $raw_struct->{'numbers'}{'percentFormats'}{'percentFormatLength'}{'percentFormat'}{'pattern'} eq 'ARRAY' ? $raw_struct->{'numbers'}{'percentFormats'}{'percentFormatLength'}{'percentFormat'}{'pattern'}->[0]
+ : $raw_struct->{'numbers'}{'percentFormats'}{'percentFormatLength'}{'percentFormat'}{'pattern'}
+ )
+ || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'percent'} ),
+ '_percent_format_percent' => $_percent_format_percent,
+ 'territory' => $raw_struct->{'localeDisplayNames'}{'codePatterns'}{'codePattern'}{'territory'}{'content'}
+ || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'territory'} ),
+ 'language' => $raw_struct->{'localeDisplayNames'}{'codePatterns'}{'codePattern'}{'language'}{'content'}
+ || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'language'} ),
+ 'locale' => ( Encode::decode_utf8( ref( $raw_struct->{'localeDisplayNames'}{'localeDisplayPattern'}{'localePattern'} ) eq 'HASH' ? $raw_struct->{'localeDisplayNames'}{'localeDisplayPattern'}{'localePattern'}{'content'} : $raw_struct->{'localeDisplayNames'}{'localeDisplayPattern'}{'localePattern'} ) )
+ || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'locale'} ), # wx_yz has no name but wx does and xy may
+ # {'localeDisplayNames'}{'localeDisplayPattern'}{'localePattern'}{'localeSeparator'} => ', ' (not needed since we only use territory subtag)
+ 'list' => {
+ '2' => $raw_struct->{'listPatterns'}{'listPattern'}{'listPatternPart'}{'2'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'list'}{'2'} ),
+ 'end' => $raw_struct->{'listPatterns'}{'listPattern'}{'listPatternPart'}{'end'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'list'}{'end'} ),
+ 'middle' => $raw_struct->{'listPatterns'}{'listPattern'}{'listPatternPart'}{'middle'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'list'}{'middle'} ),
+ 'start' => $raw_struct->{'listPatterns'}{'listPattern'}{'listPatternPart'}{'start'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'list'}{'start'} ),
+ },
+ 'ellipsis' => {
+
+ # Encode::decode_utf8() on current fallback will keep from tripping perl's hash value bytes string bug?
+ 'final' => $raw_struct->{'characters'}{'ellipsis'}{'final'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'ellipsis'}{'final'} ),
+ 'initial' => $raw_struct->{'characters'}{'ellipsis'}{'initial'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'ellipsis'}{'initial'} ),
+ 'medial' => $raw_struct->{'characters'}{'ellipsis'}{'medial'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'cldr_formats'}{'ellipsis'}{'medial'} ),
+ },
+ },
+ 'characters' => {
+ 'more_information' => (
+ ref( $raw_struct->{'characters'}{'moreInformation'} ) eq 'HASH'
+ ? ( $raw_struct->{'characters'}{'moreInformation'}{'content'} || Encode::decode_utf8( $fallback_lang_misc_info->{'characters'}{'more_information'} ) )
+ : ( $raw_struct->{'characters'}{'moreInformation'} || Encode::decode_utf8( $fallback_lang_misc_info->{'characters'}{'more_information'} ) )
+ )
+ },
+ 'delimiters' => {
+ map {
+ my $norm = $_;
+ $norm = lcfirst($norm);
+ $norm =~ s/([A-Z])/_\L$1\E/g;
+
+ # print Dumper(
+ # [
+ # $_,
+ # $norm,
+ # exists $raw_struct->{'delimiters'}{$_},
+ # $raw_struct->{'delimiters'}{$_},
+ # $fallback_lang_misc_info->{'cldr_formats'}{'delimiters'}{$norm}
+ # ]);
+ (
+ $norm => (
+ exists $raw_struct->{'delimiters'}{$_}
+ ? ( $raw_struct->{'delimiters'}{$_} || $fallback_lang_misc_info->{'delimiters'}{$norm} )
+ : $fallback_lang_misc_info->{'delimiters'}{$norm}
+ )
+ )
+ } ( 'quotationStart', 'quotationEnd', 'alternateQuotationStart', 'alternateQuotationEnd' )
+ },
+ 'plural_forms' => {
+
+ # Order is important for Locale::Maketext::Utils::quant():
+ # one (singular), two (dual), few (paucal), many, other, zero
+ 'category_list' => [
+ (
+ ( grep { exists $plural_form_entry->{$_} } ( Locales::get_cldr_plural_category_list() ) ),
+ exists $plural_form_entry->{'other'} ? () : ('other') # has to have 'other' at the end if no where else
+ )
+ ],
+ 'category_rules' => $plural_form_entry,
+ },
+ 'orientation' => {
+ 'characters' => $raw_struct->{'layout'}{'orientation'}{'characters'} || $fallback_lang_misc_info->{'orientation'}{'characters'} || 'left-to-right',
+ 'lines' => $raw_struct->{'layout'}{'orientation'}{'lines'} || $fallback_lang_misc_info->{'orientation'}{'lines'} || 'top-to-bottom',
+ },
+ 'posix' => {
+ 'yesstr' => $raw_struct->{'posix'}{'messages'}{'yesstr'} || Encode::decode_utf8( $fallback_lang_misc_info->{'posix'}{'yesstr'} ),
+ 'nostr' => $raw_struct->{'posix'}{'messages'}{'nostr'} || Encode::decode_utf8( $fallback_lang_misc_info->{'posix'}{'nostr'} ),
+
+ # TODO: yesexp/noexp
+ },
+ };
+
+ for my $k ( keys %{ $lang_misc_info->{'delimiters'} } ) {
+ if ( ref( $lang_misc_info->{'delimiters'}{$k} ) eq 'HASH' ) {
+ $lang_misc_info->{'delimiters'}{$k} = $lang_misc_info->{'delimiters'}{$k}{'content'};
+ }
+ }
+
+ for my $lng ( sort keys %{ $raw_struct->{'localeDisplayNames'}{'languages'}{'language'} } ) {
+ next if $lng eq 'root';
+
+ # if ($tag eq 'en') {
+ # next if !get_xml_file_for($lng,1);
+ # }
+
+ my $short = $lng;
+ $short =~ tr/A-Z/a-z/;
+
+ my ( $l, $t, @x ) = split( /_/, $short );
+ next if @x;
+ next if $t && !exists $terr_code_to_name->{$t};
+
+ $lang_code_to_name->{$short} = $raw_struct->{'localeDisplayNames'}{'languages'}{'language'}{$lng}{'content'};
+ $lang_name_to_code->{ Locales::normalize_for_key_lookup( $raw_struct->{'localeDisplayNames'}{'languages'}{'language'}{$lng}{'content'} ) } = $short;
+ }
+
+ if ($fallback_lang_code_to_name) {
+ for my $fb_lng ( keys %{$fallback_lang_code_to_name} ) {
+ if ( !exists $lang_code_to_name->{$fb_lng} ) {
+ $lang_code_to_name->{$fb_lng} = $fallback_lang_code_to_name->{$fb_lng};
+ $lang_name_to_code->{ Locales::normalize_for_key_lookup( $fallback_lang_code_to_name->{$fb_lng} ) } = $fb_lng;
+ }
+ }
+ }
+ #### /Languages ####
+
+ # TOOD: ? merge in ant $raw_struct->{'fallback'} (sans language part of $tag or 'en' since those happen alreay) locale's ?
+
+ return ( $lang_code_to_name, $lang_name_to_code, $lang_misc_info, $terr_code_to_name, $terr_name_to_code );
+}
+
+sub write_language_module {
+ my ( $tag, $code_to_name, $name_to_code, $misc_info ) = @_;
+
+ # init 'category_rules_compiled' key
+ Locales::plural_rule_hashref_to_code( $misc_info->{'plural_forms'} );
+
+ my $code_to_name_str = _stringify_hash($code_to_name);
+ my $name_to_code_str = _stringify_hash($name_to_code);
+ my $misc_info_str;
+ {
+
+ # make values in plural_forms->category_rules_compiled be sub { ...} instead of 'sub \{ \.\.\. \}'
+ #
+ # this adds a package thing, maybe investigate?
+ # local $Data::Dumper::Deparse = 1;
+ # for my $k (keys %{$misc_info->{plural_forms}{category_rules_compiled}}) {
+ # print "RULE $k: $misc_info->{plural_forms}{category_rules_compiled}{$k}\n";
+ # $misc_info->{plural_forms}{category_rules_compiled}{$k} = eval "$misc_info->{plural_forms}{category_rules_compiled}{$k}";
+ # }
+
+ $misc_info_str = _stringify_hash($misc_info);
+
+ for my $k ( keys %{ $misc_info->{'plural_forms'}{category_rules_compiled} } ) {
+ $misc_info_str =~ s/(\'\Q$k\E\' \=\>) \"(sub\\ \\\{.*)\"/"$1" . String::Unquotemeta::unquotemeta("$2")/e;
+ }
+
+ # print "DEBUG:\n$misc_info_str\n";exit;
+ }
+ _write_utf8_perl(
+ "Language/$tag.pm", qq{package Locales::DB::Language::$tag;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::Language::$tag\::VERSION = '$mod_version';
+
+\$Locales::DB::Language::$tag\::cldr_version = '$cldr_version';
+
+\%Locales::DB::Language::$tag\::misc_info = (
+$misc_info_str,
+);
+
+\%Locales::DB::Language::$tag\::code_to_name = (
+$code_to_name_str,
+);
+
+\%Locales::DB::Language::$tag\::name_to_code = (
+$name_to_code_str,
+);
+
+1;
+},
+ );
+}
+
+sub write_territory_module {
+ my ( $tag, $code_to_name, $name_to_code ) = @_;
+
+ my $code_to_name_str = _stringify_hash($code_to_name);
+ my $name_to_code_str = _stringify_hash($name_to_code);
+
+ _write_utf8_perl(
+ "Territory/$tag.pm", qq{package Locales::DB::Territory::$tag;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::Territory::$tag\::VERSION = '$mod_version';
+
+\$Locales::DB::Territory::$tag\::cldr_version = '$cldr_version';
+
+\%Locales::DB::Territory::$tag\::code_to_name = (
+$code_to_name_str,
+);
+
+\%Locales::DB::Territory::$tag\::name_to_code = (
+$name_to_code_str,
+);
+
+1;
+
+},
+ );
+
+}
+
+my @_get_fast_norm_test_data = ( '', 0 );
+
+sub _get_fast_norm_test_data {
+ if ( $_get_fast_norm_test_data[1] == 0 ) {
+ my $loc = Locales->new();
+ my $cnt = 12;
+ for my $l ( sort $loc->get_language_codes() ) {
+ $_get_fast_norm_test_data[0] .= qq{is(\$self_obj->get_locale_display_pattern_from_code('$l'), \$self_obj->get_locale_display_pattern_from_code_fast('$l'), 'get_locale_display_pattern_from_code[_fast] same result for $l');\n};
+ $_get_fast_norm_test_data[1]++;
+
+ $_get_fast_norm_test_data[0] .= qq{is(\$self_obj->get_character_orientation_from_code('$l'), \$self_obj->get_character_orientation_from_code('$l'), 'get_character_orientation_from_code[_fast] same result for $l');\n};
+ $_get_fast_norm_test_data[1]++;
+
+ $_get_fast_norm_test_data[0] .= "\n";
+ }
+ }
+
+ return @_get_fast_norm_test_data;
+}
+
+sub write_locale_test {
+ my ($tag) = @_;
+
+ my ( $fast_norm_str, $fast_norm_cnt ) = _get_fast_norm_test_data();
+
+ _write_utf8_perl(
+ "../../../t/042.$tag.t", qq{
+# Auto generated during CLDR build
+
+use Test::More tests => 13 + $fast_norm_cnt;
+
+use lib 'lib', '../lib';
+
+BEGIN {
+use_ok( 'Locales::DB::Language::$tag' );
+use_ok( 'Locales::DB::Territory::$tag' );
+}
+
+diag( "Sanity checking Locales::DB::Language::$tag \$Locales::DB::Language::$tag\::VERSION DB" );
+
+use Locales;
+use Locales::DB::Language::en;
+use Locales::DB::Territory::en;
+
+my \@en_lang_codes = sort(keys \%Locales::DB::Language::en::code_to_name);
+my \@en_terr_codes = sort(keys \%Locales::DB::Territory::en::code_to_name);
+
+my \@my_lang_codes = sort(keys \%Locales::DB::Language::$tag\::code_to_name);
+my \@my_terr_codes = sort(keys \%Locales::DB::Territory::$tag\::code_to_name);
+my \%lang_lu;
+my \%terr_lu;
+\@lang_lu{ \@my_lang_codes } = ();
+\@terr_lu{ \@my_terr_codes } = ();
+ok(\$Locales::DB::Language::$tag\::cldr_version eq \$Locales::cldr_version, 'CLDR version is correct');
+ok(\$Locales::DB::Language::$tag\::VERSION eq (\$Locales::VERSION - $v_offset), 'VERSION is correct');
+
+ok(!(grep {!exists \$lang_lu{\$_} } \@en_lang_codes), '$tag languages contains en');
+ok(!(grep {!exists \$terr_lu{\$_} } \@en_terr_codes), '$tag territories contains en');
+
+my \%uniq = ();
+grep { not \$uniq{\$_}++ } \@{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_list'} };
+is_deeply(
+ [ sort \@{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_list'} }],
+ [ sort keys \%uniq ],
+ "'category_list' contains no duplicates"
+);
+
+ok(grep(m/^other\$/, \@{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_list'} }), "'category_list' has 'other'");
+
+is_deeply(
+ [ grep !m/^other\$/, sort \@{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_list'} }],
+ [ grep !m/^other\$/, sort keys \%{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_rules'} } ],
+ "'category_rules' has necessary 'category_list' items"
+);
+
+is_deeply(
+ [ sort keys \%{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_rules'} } ],
+ [ sort keys \%{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_rules_compiled'} } ],
+ "each 'category_rules' has a 'category_rules_compiled'"
+);
+my \$ok_rule_count = 0;
+my \$error = '';
+for my \$rule (keys \%{\$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_rules_compiled'}}) {
+ if (ref(\$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_rules_compiled'}{\$rule}) eq 'CODE') {
+ \$ok_rule_count++;
+ next;
+ }
+ eval \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_rules_compiled'}{\$rule};
+ if (\$@) {
+ \$error .= \$@;
+ next;
+ }
+ else {
+ \$ok_rule_count++;
+ }
+}
+ok(\$ok_rule_count == keys \%{ \$Locales::DB::Language::$tag\::misc_info{'plural_forms'}->{'category_rules_compiled'} }, "each 'category_rules_compiled' eval without error - count");
+is(\$error, '', "each 'category_rules_compiled' is a code ref or evals without error - errors");
+
+my \$self_obj = Locales->new('$tag');
+ok(ref(\$self_obj), '$tag object created OK');
+
+$fast_norm_str
+
+ },
+ "t/042.$tag.t",
+ );
+}
+
+sub write_get_plural_form_test {
+ my ($tag) = @_;
+
+ my $loc = Locales->new($tag) || die die "Could not create object for $tag: \$@";
+
+ my $arg_tests_count = 2;
+ if ( $loc->get_plural_form(0) eq 'other' ) {
+ $arg_tests_count = 4;
+ }
+
+ _write_utf8_perl(
+ "../../../t/06.$tag.t", qq{
+# Auto generated during CLDR build
+
+use lib 'lib', '../lib';
+use Test::More;
+
+use Locales;
+
+diag( "Verifying perl and js get_plural_form() behave the same for $tag." );
+
+if (!\$ENV{'RELEASE_TESTING'}) {
+ plan 'skip_all' => 'These tests are only run under RELEASE_TESTING.';
+}
+
+my \$obj = Locales->new('$tag') || die "Could not create object for $tag: \$@";
+
+my \@nums = ( 0, 1.6, 2.2, 3.14159, 42.78, 0 .. 256 );
+
+eval 'use JE ()';
+plan \$@ ? ( 'skip_all' => 'JE.pm required for testing JS/Perl plural behavior tests' ) : ( 'tests' => ( scalar(\@nums) * (4 + $arg_tests_count) ) );
+my \$js = JE->new();
+
+use File::Slurp;
+my \$root = '.'; # TODO: make me portable
+if ( -d '../share/' ) {
+ \$root = '..';
+}
+if ( !-d "\$root/share/" ) {
+ die "Can not determine share directory.";
+}
+
+my \@cats = map { "args_\$_" } \$obj->get_plural_form_categories();
+my \$cats_args = join(', ', map { "'\$_'" } \@cats);
+
+my \$jsfile = File::Slurp::read_file("\$root/share/functions/\$obj->{'locale'}.js") or die "Could not read '\$root/share/functions/\$obj->{'locale'}.js': \$!";
+
+for my \$n (\@nums) {
+ my \$res = \$js->eval("var X = \$jsfile;return X.get_plural_form(\$n)");
+ is_deeply(
+ [ \$res->[0], \$res->[1] ], # have to do this to stringify JE object properly
+ [ \$obj->get_plural_form(\$n) ],
+ "perl and js get_plural_form() behave the same. Tag: \$obj->{'locale'} Number: \$n"
+ );
+ is(\$res->[1], 0, "using special is 0 for \$n (no args)");
+
+ my \$res_n = \$js->eval("var X = \$jsfile;return X.get_plural_form(-\$n)");
+ is_deeply(
+ [ \$res_n->[0], \$res_n->[1] ], # have to do this to stringify JE object properly
+ [ \$obj->get_plural_form("-\$n") ],
+ "perl and js get_plural_form() behave the same. Tag: \$obj->{'locale'} Number: -\$n"
+ );
+ is(\$res_n->[1], 0, "using special is 0 for -\$n (no args)");
+
+ my \$res_s = \$js->eval("var X = \$jsfile;return X.get_plural_form(\$n,\$cats_args)");
+ is_deeply(
+ [ \$res_s->[0], \$res_s->[1] ], # have to do this to stringify JE object properly
+ [ \$obj->get_plural_form(\$n,\@cats) ],
+ "perl and js get_plural_form() behave the same. Tag: \$obj->{'locale'} Number: \$n"
+ );
+ is(\$res_s->[1], 0, "using special is 0 for \$n (args w/ no spec zero)");
+
+ if ($arg_tests_count == 4) {
+ my \$res_n = \$js->eval("var X = \$jsfile;return X.get_plural_form(\$n, \$cats_args, 'spec_zeroth')");
+ is_deeply(
+ [ \$res_n->[0], \$res_n->[1] ], # have to do this to stringify JE object properly
+ [ \$obj->get_plural_form("\$n",\@cats, 'spec_zeroth') ],
+ "perl and js get_plural_form() behave the same. Tag: \$obj->{'locale'} Number: \$n"
+ );
+ my \$spec_bool = \$n == 0 ? 1 : 0;
+ is(\$res_n->[1], \$spec_bool, "using special is \$spec_bool for \$n (args w/ spec zero)");
+ }
+
+ # TODO: ? too many/too few args and check for carp ?
+}
+ },
+ "t/06.$tag.t",
+ );
+}
+
+sub write_native_module {
+ my ( $native_map, $fallback_lookup ) = @_;
+
+ my $code_to_name_str = _stringify_hash_no_dumper($native_map);
+ my $fallback_lookup_str = _stringify_hash_no_dumper($fallback_lookup);
+
+ # nerd alert! TODO: verify during next build
+ if ( $code_to_name_str->{'tlh'} eq 'Klingon' ) { # i.e. no CLDR data for tlh
+
+ # "\x{f8e4}\x{f8d7}\x{f8dc}\x{f8d0}\x{f8db}"
+ # "\xef\xa3\xa4\xef\xa3\x97\xef\xa3\x9c\xef\xa3\x90\xef\xa3\x9b"
+ $code_to_name_str->{'tlh'} = ""; # need a font to see this, like Bengali
+ }
+
+ _write_utf8_perl(
+ "$locales_db/Native.pm", qq{package Locales::DB::Native;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::Native::VERSION = '$mod_version';
+
+\$Locales::DB::Native::cldr_version = '$cldr_version';
+
+\%Locales::DB::Native::code_to_name = (
+$code_to_name_str);
+
+\%Locales::DB::Native::value_is_fallback = (
+$fallback_lookup_str);
+
+1;
+},
+ 'lib/Locales/DB/Native.pm',
+ 1,
+ );
+}
+
+sub write_db_loadable_module {
+ my $en = Locales->new('en');
+
+ my $code_hr;
+ my $terr_hr;
+
+ for my $t ( $en->get_territory_codes() ) {
+ $terr_hr->{$t} = 1;
+ }
+
+ for my $c ( $en->get_language_codes() ) {
+ next if Locales::is_non_locale($c);
+
+ if ( Locales->new($c) ) {
+ $code_hr->{$c} = 1;
+ }
+ }
+
+ my $code_str = _stringify_hash_no_dumper($code_hr);
+ my $terr_str = _stringify_hash_no_dumper($terr_hr);
+
+ _write_utf8_perl(
+ "$locales_db/Loadable.pm", qq{package Locales::DB::Loadable;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::Loadable::VERSION = '$mod_version';
+
+\$Locales::DB::Loadable::cldr_version = '$cldr_version';
+
+\%Locales::DB::Loadable::code = (
+$code_str);
+
+\%Locales::DB::Loadable::territory = (
+$terr_str);
+
+1;
+ },
+ 'lib/Locales/DB/Loadable.pm',
+ 1,
+ );
+
+}
+
+sub write_character_orientation_module {
+ my ( $text_direction_map, $fallback_lookup ) = @_;
+
+ my $code_to_name_str = _stringify_hash_no_dumper($text_direction_map);
+ my $fallback_lookup_str = _stringify_hash_no_dumper($fallback_lookup);
+
+ _write_utf8_perl(
+ "$locales_db/CharacterOrientation.pm", qq{package Locales::DB::CharacterOrientation;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::CharacterOrientation::VERSION = '$mod_version';
+
+\$Locales::DB::CharacterOrientation::cldr_version = '$cldr_version';
+
+\%Locales::DB::CharacterOrientation::code_to_name = (
+$code_to_name_str);
+
+\%Locales::DB::CharacterOrientation::value_is_fallback = (
+$fallback_lookup_str);
+
+1;
+},
+ 'lib/Locales/DB/CharacterOrientation.pm',
+ 1,
+ );
+
+ File::Path::Tiny::mk("$locales_db/CharacterOrientation") || die "Could not create '$locales_db/CharacterOrientation': $!";
+ my $rtl;
+ for my $name ( keys %{$text_direction_map} ) {
+ if ( $text_direction_map->{$name} eq 'right-to-left' ) {
+ $rtl->{$name} = undef();
+ }
+ elsif ( $text_direction_map->{$name} ne 'left-to-right' ) {
+ warn "$name is neither right-to-left or left-to-right";
+ }
+ }
+ die "Locales::DB::CharacterOrientation::Tiny lookup hash not built" if ref($rtl) ne 'HASH';
+ $rtl = _stringify_hash_no_dumper($rtl);
+
+ _write_utf8_perl(
+ "$locales_db/CharacterOrientation/Tiny.pm", qq{package Locales::DB::CharacterOrientation::Tiny;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::CharacterOrientation::Tiny::VERSION = '$mod_version';
+
+\$Locales::DB::CharacterOrientation::Tiny::cldr_version = '$cldr_version';
+
+my \%rtl = (
+$rtl);
+
+sub get_orientation {
+ if ( exists \$rtl{ \$_[0] } ) {
+ return 'right-to-left';
+ }
+ else {
+ require Locales;
+ my (\$l) = Locales::split_tag(\$_[0]);
+ if (\$l ne \$_[0]) {
+ return 'right-to-left' if exists \$rtl{ \$l };
+ }
+ return 'left-to-right';
+ }
+}
+
+1;
+},
+ 'lib/Locales/DB/CharacterOrientation/Tiny.pm',
+ 1,
+ );
+}
+
+sub write_name_pattern_module {
+ my ( $name_pattern, $isfallback ) = @_;
+
+ my $name_pattern_str = _stringify_hash_no_dumper($name_pattern);
+ my $fallback_lookup_str = _stringify_hash_no_dumper($isfallback);
+
+ _write_utf8_perl(
+ "$locales_db/LocaleDisplayPattern.pm", qq{package Locales::DB::LocaleDisplayPattern;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::LocaleDisplayPattern::VERSION = '$mod_version';
+
+\$Locales::DB::LocaleDisplayPattern::cldr_version = '$cldr_version';
+
+\%Locales::DB::LocaleDisplayPattern::code_to_pattern = (
+$name_pattern_str);
+
+\%Locales::DB::LocaleDisplayPattern::value_is_fallback = (
+$fallback_lookup_str);
+
+1;
+},
+ 'lib/Locales/DB/LocaleDisplayPattern.pm',
+ 1,
+ );
+
+ # $locales_db/LocaleDisplayPattern
+ File::Path::Tiny::mk("$locales_db/LocaleDisplayPattern") || die "Could not create '$locales_db/CharacterOrientation': $!";
+
+ my $name_pattern_hr;
+
+ require Locales::DB::Language::en;
+ my $default_pattern = $Locales::DB::Language::en::misc_info{'cldr_formats'}{'locale'};
+ for my $k ( keys %{$name_pattern} ) {
+ next if !$name_pattern->{$k} || $name_pattern->{$k} =~ m/^\s+$/ || $name_pattern->{$k} eq $default_pattern;
+ $name_pattern_hr->{$k} = $name_pattern->{$k};
+ }
+
+ die "Locales::DB::LocaleDisplayPattern::Tiny lookup hash not built" if ref($name_pattern_hr) ne 'HASH';
+ $name_pattern_hr = _stringify_hash_no_dumper($name_pattern_hr);
+
+ $default_pattern = quotemeta($default_pattern);
+
+ # $locales_db/LocaleDisplayPattern/Tiny.pm
+ _write_utf8_perl(
+ "$locales_db/LocaleDisplayPattern/Tiny.pm", qq{package Locales::DB::LocaleDisplayPattern::Tiny;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::LocaleDisplayPattern::Tiny::VERSION = '$mod_version';
+
+\$Locales::DB::LocaleDisplayPattern::Tiny::cldr_version = '$cldr_version';
+
+my \%locale_display_lookup = (
+$name_pattern_hr);
+
+sub get_locale_display_pattern {
+ if ( exists \$locale_display_lookup{ \$_[0] } ) {
+ return \$locale_display_lookup{ \$_[0] };
+ }
+ else {
+ require Locales;
+ my (\$l) = Locales::split_tag(\$_[0]);
+ if (\$l ne \$_[0]) {
+ return \$locale_display_lookup{\$l} if exists \$locale_display_lookup{ \$l };
+ }
+ return "$default_pattern";
+ }
+}
+
+1;
+},
+ 'lib/Locales/DB/LocaleDisplayPattern/Tiny.pm',
+ 1,
+ );
+}
+
+sub write_plural_forms_argument_pod {
+ my ( $plural_forms, $isfallback ) = @_;
+ File::Path::Tiny::mk("$locales_db/Docs") || die "Could not create '$locales_db/Docs': $!";
+
+ my $pod_starts = '__END__'; # this is to help prevent mis-parsing for CPAN like rt 76129 (probably not necessary)
+ my $pkg = 'Locales::DB::Docs::PluralForms'; # this is to help prevent mis-parsing for CPAN like rt 76129
+ my $pod_mark = '='; # this is to help prevent mis-parsing for CPAN like rt 80546 (and not fixed *again* in 0.28)
+ my $pod_items = '';
+
+ for my $ent ( @{$plural_forms} ) {
+
+ if ( exists $isfallback->{ $ent->{'tag'} } ) {
+ $pod_items .= "=item $ent->{'tag'}\n\nCLDR $cldr_version did not define data for “$ent->{'tag'}”, thus it will fallback to L</en> behavior.\n\nYou can L<submit the missing data to the CLDR|http://unicode.org/cldr/trac> if you wish.\n\n";
+ }
+ else {
+ $pod_items .= "=item $ent->{'tag'}\n\n$fb get_plural_form(\$n, $ent->{'csv'})\n";
+ if ( $ent->{'zero_is_not_other'} ) {
+ $pod_items .= "\nNote: zero falls under a different category than “other” so there is no L</“Special Zero” Argument> for $ent->{'tag'}\n\n";
+ }
+ else {
+ $pod_items .= " get_plural_form(\$n, $ent->{'csv'}, special_zero)\n\n";
+ }
+ }
+ }
+
+ # $locales_db/Docs/PluralForms.pm
+ _write_utf8_perl(
+ "$locales_db/Docs/PluralForms.pm", qq{package $pkg;
+
+use strict;
+use warnings;
+
+# Auto generated from CLDR
+use if \$Locales::_UNICODE_STRINGS, 'utf8';
+
+\$Locales::DB::Docs::PluralForms::VERSION = '$mod_version';
+
+\$Locales::DB::Docs::PluralForms::cldr_version = '$cldr_version';
+
+1;
+
+$pod_starts
+
+${pod_mark}encoding utf-8
+
+${pod_mark}head1 NAME
+
+Locales::DB::Docs::PluralForms - plural form details reference for all
+included locales
+
+${pod_mark}head1 VERSION
+
+Locales.pm v$mod_version (based on CLDR v$cldr_version)
+
+${pod_mark}head1 DESCRIPTION
+
+CLDR L<defines a set of broad plural categories and rules|http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html> that determine which category any given number will fall under.
+
+L<Locales> allows you to determine the plural categories applicable to a specific locale and also which category a given number will fall under in that locale.
+
+This POD documents which categories and in what order you'd specify them in additional arguments to L<Locales/get_plural_form()> (i.e. the optional arguments after the number).
+
+${pod_mark}head2 “Special Zero” Argument
+
+In addition to the CLDR category value list you can also specify one additional argument of what to use for zero instead of the value for “other”.
+
+This won't be used if 0 falls under a specific category besides “other”.
+
+${pod_mark}head1 Plural Category Argument Order Reference
+
+${pod_mark}over 4
+
+$pod_items
+
+${pod_mark}back
+
+${pod_mark}head1 BUGS AND LIMITATIONS
+
+Please see L<Locales/BUGS AND LIMITATIONS>
+
+${pod_mark}head2 BEFORE YOU SUBMIT A BUG REPORT
+
+Please see L<Locales/BEFORE YOU SUBMIT A BUG REPORT>
+
+${pod_mark}head1 AUTHOR
+
+Daniel Muey C<< <http://drmuey.com/cpan_contact.pl> >>
+
+${pod_mark}head1 LICENCE AND COPYRIGHT
+
+Copyright (c) 2009, Daniel Muey C<< <http://drmuey.com/cpan_contact.pl> >>. All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself. See L<perlartistic>.
+
+${pod_mark}head1 DISCLAIMER OF WARRANTY
+
+BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE SOFTWARE "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 SOFTWARE IS WITH
+YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR, OR CORRECTION.
+
+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 SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
+OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+THE SOFTWARE (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 SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+},
+ 'lib/Locales/DB/Docs/PluralForms.pm',
+ 1,
+ );
+}
+
+sub build_javascript_share {
+ my ($tag) = @_;
+
+ if ( -d 'share/' ) {
+ File::Path::Tiny::rm('share/') || die "Could not remove 'share/': $!";
+ }
+ for my $d (qw(misc_info/ functions/ code_to_name/ datetime/ db/)) {
+ File::Path::Tiny::mk("share/$d") || die "Could not create 'share/$d': $!";
+ }
+
+ my $loc = Locales->new();
+ for my $tag ( sort $loc->get_language_codes() ) {
+ my $tag_loc = Locales->new($tag) || next;
+
+ my $guts_m = $tag_loc->{'language_data'}{'misc_info'};
+ for my $k ( keys %{ $guts_m->{'plural_forms'}{'category_rules_compiled'} } ) {
+ $guts_m->{'plural_forms'}{'category_rules_compiled'}{$k} = Locales::plural_rule_string_to_javascript_code( $guts_m->{'plural_forms'}{'category_rules'}{$k}, $k );
+ }
+ my $json = JSON::Syck::Dump($guts_m); # no eval, lets just die
+ $json =~ s/\"(function \(n\) \{)/$1/g;
+ $json =~ s/(return\;\})\"/$1/g;
+
+ open( my $fh_m, '>', "share/misc_info/$tag.js" ) or die "Could not open 'share/misc_info/$tag.js': $!";
+ print {$fh_m} $json;
+ close $fh_m;
+
+ my $cats_list_js = JSON::Syck::Dump( $guts_m->{'plural_forms'}{'category_list'} );
+ my $cats_proc_js = JSON::Syck::Dump( [ Locales::get_cldr_plural_category_list(1) ] );
+ my $cats_rule_js = JSON::Syck::Dump( $guts_m->{'plural_forms'}{'category_rules_compiled'} );
+ $cats_rule_js =~ s/"(function[^"]+)"/$1/g;
+
+ open( my $fh_f, '>', "share/functions/$tag.js" ) or die "Could not open 'share/functions/$tag.js': $!";
+
+ # var category_process_order = $cats_proc_js;
+ # var category_rules_lookup = $cats_rule_js;
+ # var categories = $cats_list_js;
+
+ my $js_code = <<"END_FUNC";
+{
+ 'get_plural_form' : function (n) {
+ var category;
+ var category_values = Array.prototype.slice.call(arguments,1);
+
+ var has_extra_for_zero = 0;
+ var abs_n = Math.abs(n);
+ var category_process_order = $cats_proc_js;
+ var category_rules_lookup = $cats_rule_js;
+
+ for (i=0; i < category_process_order.length; i++) {
+ if (category_rules_lookup[category_process_order[i]]) {
+ category = category_rules_lookup[category_process_order[i]](abs_n);
+ if (category) break;
+ }
+ }
+
+ var categories = $cats_list_js;
+
+ if ( category_values.length === 0 ) {
+ category_values = categories; // no args will return the category name
+ }
+ else {
+ var cat_len = categories.length;
+ var val_len = category_values.length;
+
+ var cat_len_plus_one = cat_len + 1;
+ if ( val_len === cat_len_plus_one ) {
+ has_extra_for_zero++;
+ }
+ else if ( cat_len !== val_len ) {
+ if (window.console) console.warn( 'The number of given values (' + val_len + ') does not match the number of categories (' + cat_len + ').' );
+ }
+ }
+
+ if ( category === undefined) {
+ var cat_idx = has_extra_for_zero && abs_n !== 0 ? -2 : -1;
+ var sliced = category_values.slice(cat_idx);
+ return [sliced[0], has_extra_for_zero && abs_n === 0 ? 1 : 0];
+ }
+ else {
+ var return_value;
+ GET_POSITION:
+ while(1) {
+ var cat_pos_in_list;
+ var index = -1;
+ CATEGORY:
+ for (i=0; i < categories.length; i++ ) {
+ index++;
+ if ( categories[i] === category ) {
+ cat_pos_in_list = index;
+ break CATEGORY;
+ }
+ }
+
+ if ( cat_pos_in_list === undefined && category !== 'other' ) {
+ if (window.console) console.warn( 'The category (' + category + ') is not used by this locale.');
+ category = 'other';
+ continue GET_POSITION;
+ }
+ else if ( cat_pos_in_list === undefined) {
+ var cat_idx = has_extra_for_zero && abs_n !== 0 ? -2 : -1;
+ var sliced = category_values.slice(cat_idx);
+ return_value = [sliced[0], has_extra_for_zero && abs_n === 0 ? 1 : 0]
+ break GET_POSITION;
+ }
+ else {
+ if ( has_extra_for_zero && category === 'other' ) {
+ var cat_idx = has_extra_for_zero && abs_n === 0 ? -1 : cat_pos_in_list;
+ var sliced = category_values.slice(cat_idx);
+ return_value = [sliced[0], has_extra_for_zero && abs_n === 0 ? 1 : 0];
+ break GET_POSITION;
+ }
+ else {
+ return_value = [category_values[cat_pos_in_list], 0];
+ break GET_POSITION;
+ }
+ }
+ break GET_POSITION;
+ }
+
+ return return_value;
+ }
+ }
+}
+END_FUNC
+ print {$fh_f} JavaScript::Minifier::XS::minify($js_code);
+ close $fh_f;
+
+ my $json_c = JSON::Syck::Dump( $tag_loc->{'language_data'}{'code_to_name'} ); # no eval, lets just die
+
+ open( my $fh_c, '>', "share/code_to_name/$tag.json" ) or die "Could not open 'share/code_to_name/$tag.json': $!";
+ print {$fh_c} $json_c;
+ close $fh_c;
+
+ my $dt_struct;
+ my $dt_loc = eval { DateTime::Locale->load( Locales::normalize_tag_for_datetime_locale($tag) ) };
+ if ($@) {
+
+ # Locales has $tag but DateTime::Locales does not (different CLDR version probably)
+ print "$tag datetime JSON will be en: $@";
+ $dt_loc = DateTime::Locale->load('en');
+ }
+
+ for my $format (@dt_available_formats) {
+ $dt_struct->{'format_for'}{$format} = $dt_loc->format_for($format); # no eval, should die since it means incomplete data
+ }
+ for my $meth (@dt_methods) {
+ my $res = $dt_loc->$meth();
+ $dt_struct->{$meth} =
+ ref($res) eq 'ARRAY' ? [ @{$res} ]
+ : ref($res) eq 'HASH' ? { %{$res} }
+ : $res;
+ }
+
+ my $json_d = JSON::Syck::Dump($dt_struct); # no eval, lets just die
+ open( my $fh_d, '>', "share/datetime/$tag.json" ) or die "Could not open 'share/datetime/$tag.json': $!";
+ print {$fh_d} $json_d;
+ close $fh_d;
+
+ append_file( $manifest, "share/misc_info/$tag.js\nshare/code_to_name/$tag.json\nshare/datetime/$tag.json\nshare/functions/$tag.js\n" );
+ }
+
+ require Locales::DB::Loadable;
+ my $json_d = JSON::Syck::Dump( { 'code' => \%Locales::DB::Loadable::code, 'territory' => \%Locales::DB::Loadable::territory } ); # no eval, lets just die
+ open( my $fh_d, '>', "share/db/loadable.json" ) or die "Could not open 'share/db/loadable.json': $!";
+ print {$fh_d} $json_d;
+ close $fh_d;
+
+ append_file( $manifest, "share/db/loadable.json" );
+}
+
+sub build_manifest {
+ my $base = $manifest;
+ $base =~ s{\.build$}{};
+ my @in = read_file("$base.in");
+ my @bl = read_file("$base.build");
+ write_file( $base, @in, @bl );
+}
+
+sub do_changelog {
+ my $changelog = $manifest;
+ $changelog =~ s{MANIFEST\.build$}{Changes};
+ my @cl = read_file($changelog);
+ return if grep /^$Locales::VERSION\s+/, @cl;
+
+ my $time = localtime();
+ my $new_ent = <<"END_CL";
+$Locales::VERSION $time
+ - Updated data to CLDR $Locales::cldr_version
+
+END_CL
+ write_file( $changelog, $new_ent, @cl );
+}
+
+sub _write_utf8_perl {
+ my ( $file, $guts, $mani, $open_plain ) = @_;
+
+ my $open = $open_plain ? '>' : '>:utf8'; #:utf8 breaks Native.pm
+
+ open( my $fh, $open, $file ) or die "Could not open '$file': $!";
+ print {$fh} $guts;
+ close $fh;
+
+ system( qw(perltidy -b), $file ) == 0 || die "perltidy failed, '$file' probably has syntax errors";
+ unlink "$file.bak";
+
+ append_file( $manifest, $mani ? "$mani\n" : "lib/Locales/DB/$file\n" );
+}
+
+sub _stringify_hash_no_dumper {
+ my $string;
+ for my $k ( keys %{ $_[0] } ) {
+ my $qk = $k;
+ my $qv = $_[0]->{$k};
+ $qk =~ s{\'}{\\\'}g;
+ $qv =~ s{\'}{\\\'}g;
+ my $ky = $k ne $qk ? qq{"$qk"} : qq{'$k'};
+ my $vl = $_[0]->{$k} ne $qv ? qq{"$qv"} : qq{'$_[0]->{$k}'};
+ $string .= "$ky => $vl,\n";
+ }
+ return $string;
+}
+
+sub _stringify_hash {
+ my $string = Dumper( $_[0] );
+ $string =~ s/^\s*\{\s*//;
+ $string =~ s/\s*\}\s*$//;
+ return $string;
+}
+
+1;
diff --git a/_build/cldr2en b/_build/cldr2en
new file mode 100755
index 0000000..b0ab59c
--- /dev/null
+++ b/_build/cldr2en
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+
+use lib '_build';
+use _locales_build_utils;
+
+my ( $cldr_db_path, $locales_db, $manifest ) = _locales_build_utils::init_paths_from_argv();
+
+File::Path::Tiny::rm($locales_db) || die "Could not remove '$locales_db': $!";
+File::Path::Tiny::mk($locales_db) || die "Could not create '$locales_db': $!";
+
+unlink $manifest;
+die "Could not clear '$manifest': $!" if -e $manifest;
+
+chdir $locales_db || die "Could not change into '$locales_db': $!";
+
+unlink glob('../../../t/042.*.t');
+unlink glob('../../../share/*/*');
+
+for my $type qw(Language Territory) {
+ File::Path::Tiny::mk($type) || die "Could not create '$type': $!";
+}
+
+my @root = _locales_build_utils::get_target_structs_from_cldr_for_tag( 'root', {}, {}, {} );
+
+my ( $lang_code_to_name, $lang_name_to_code, $lang_misc_info, $terr_code_to_name, $terr_name_to_code ) = _locales_build_utils::get_target_structs_from_cldr_for_tag( 'en', @root[ 0, 3, 2 ] ) or die "Could not get data for 'en'";
+
+_locales_build_utils::write_language_module( 'en', $lang_code_to_name, $lang_name_to_code, $lang_misc_info );
+
+_locales_build_utils::write_territory_module( 'en', $terr_code_to_name, $terr_name_to_code );
+
+_locales_build_utils::write_locale_test('en');
+
+_locales_build_utils::write_get_plural_form_test('en');
diff --git a/_build/cldr2locales b/_build/cldr2locales
new file mode 100755
index 0000000..7e3467c
--- /dev/null
+++ b/_build/cldr2locales
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+use lib '_build';
+use _locales_build_utils;
+
+my ( $cldr_db_path, $locales_db ) = _locales_build_utils::init_paths_from_argv();
+
+print "Starting 'en' ...\n";
+system( './_build/cldr2en', $cldr_db_path, $locales_db ) == 0 || die "Could not build 'en'";
+
+require Locales::DB::Language::en;
+
+my $text_direction_map = {
+ 'en' => $Locales::DB::Language::en::misc_info{'orientation'}{'characters'},
+};
+my $native_map = {
+ 'en' => $Locales::DB::Language::en::code_to_name{'en'},
+};
+my $name_pattern = {
+ 'en' => $Locales::DB::Language::en::misc_info{'cldr_formats'}{'locale'},
+};
+
+my %isfallback;
+my @plural_forms;
+for my $tag ( sort keys %Locales::DB::Language::en::code_to_name ) {
+ if ( $tag eq 'en' ) {
+ my $en = Locales->new('en');
+ push @plural_forms, { 'tag' => $tag, 'csv' => join( ', ', $en->get_plural_form_categories() ), 'zero_is_not_other' => ( $en->get_plural_form(0) ne 'other' ? 1 : 0 ) };
+ next;
+ }
+
+ print "Starting '$tag' ...\n";
+ if ( _locales_build_utils::get_xml_file_for( $tag, 1 ) ) {
+ system( './_build/en2mod', $cldr_db_path, $locales_db, $tag ) == 0 || die "Could not build '$tag'";
+ }
+ else {
+ print "No XML file for $tag\n";
+ }
+
+ if ( my $loc = Locales->new($tag) ) {
+ no strict 'refs';
+ $text_direction_map->{$tag} = ${"Locales::DB::Language::$tag\::misc_info"}{'orientation'}{'characters'};
+ $native_map->{$tag} = $loc->get_language_from_code($tag);
+ $name_pattern->{$tag} = ${"Locales::DB::Language::$tag\::misc_info"}{'cldr_formats'}{'locale'};
+ push @plural_forms, { 'tag' => $tag, 'csv' => join( ', ', $loc->get_plural_form_categories() ), 'zero_is_not_other' => ( $loc->get_plural_form(0) ne 'other' ? 1 : 0 ) };
+ }
+ else {
+ $text_direction_map->{$tag} = $text_direction_map->{'en'}; # default to 'en' since $tag has no data in CLDR
+ $native_map->{$tag} = $Locales::DB::Language::en::code_to_name{$tag}; # default to 'en' since $tag has no data in CLDR
+ $name_pattern->{$tag} = $Locales::DB::Language::en::misc_info{'cldr_formats'}{'locale'}; # default to 'en' since $tag has no data in CLDR
+ push @plural_forms, { 'tag' => $tag };
+ $isfallback->{$tag} = 1;
+ }
+}
+
+_locales_build_utils::write_native_module( $native_map, $isfallback );
+
+_locales_build_utils::write_character_orientation_module( $text_direction_map, $isfallback );
+
+_locales_build_utils::write_name_pattern_module( $name_pattern, $isfallback );
+
+_locales_build_utils::write_plural_forms_argument_pod( \@plural_forms, $isfallback );
+
+_locales_build_utils::write_db_loadable_module();
+
+_locales_build_utils::build_javascript_share();
+
+_locales_build_utils::build_manifest();
+
+_locales_build_utils::do_changelog();
diff --git a/_build/en2mod b/_build/en2mod
new file mode 100755
index 0000000..54513f6
--- /dev/null
+++ b/_build/en2mod
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+
+use lib '_build';
+use _locales_build_utils;
+
+my ( $cldr_db_path, $locales_db, $manifest ) = _locales_build_utils::init_paths_from_argv();
+
+# use Data::Dumper;print Dumper($_locales_build_utils::plural_forms);
+
+chdir $locales_db || die "Could not change into '$locales_db': $!";
+
+my $tag = Locales::normalize_tag( $ARGV[2] );
+my ( $l, $t ) = Locales::split_tag($tag);
+
+my @root;
+if ( $l ne $tag ) {
+ print "Fetching root for $tag ($l)\n";
+ @root = ( _locales_build_utils::get_target_structs_from_cldr_for_tag( $l, {}, {}, {} ) )[ 0, 3, 2 ];
+
+ # use Data::Dumper;print Dumper($root[2]);
+}
+
+require Locales::DB::Language::en;
+require Locales::DB::Territory::en;
+
+if (@root) {
+
+ # merge \%Locales::DB::Language::en::code_to_name into $root[0]
+ for my $k ( keys %Locales::DB::Language::en::code_to_name ) {
+ if ( !exists $root[0]->{$k} ) {
+ $root[0]->{$k} = $Locales::DB::Language::en::code_to_name{$k};
+ }
+ }
+
+ # merge \%Locales::DB::Territory::en::code_to_name into $root[1]
+ for my $k ( keys %Locales::DB::Territory::en::code_to_name ) {
+ if ( !exists $root[1]->{$k} ) {
+ $root[1]->{$k} = $Locales::DB::Territory::en::code_to_name{$k};
+ }
+ }
+
+ # merge \%Locales::DB::Language::en::misc_info into $root[2]
+
+ # use Data::Dumper;
+ # print Dumper( [ 'pre-merge', $root[2] ] );
+ $root[2] = _locales_build_utils::merge_hash( $root[2], \%Locales::DB::Language::en::misc_info );
+
+ # use Data::Dumper;
+ # print Dumper( [ 'pst-merge', $root[2] ] );
+
+ # $root[2] = {
+ # # 'fallback' => $fallback,
+ # # 'cldr_formats' => {
+ # # 'decimal' => $root[2]->{'numbers'}{'decimalFormats'}{'decimalFormatLength'}{'decimalFormat'}{'pattern'} || $Locales::DB::Language::en::misc_info{'cldr_formats'}{'decimal'},
+ # # 'percent' => $root[2]->{'numbers'}{'percentFormats'}{'percentFormatLength'}{'percentFormat'}{'pattern'} || $Locales::DB::Language::en::misc_info{'cldr_formats'}{'percent'},
+ # # 'territory' => $root[2]->{'localeDisplayNames'}{'codePatterns'}{'codePattern'}{'territory'}{'content'} || $Locales::DB::Language::en::misc_info{'cldr_formats'}{'territory'},
+ # # 'language' => $root[2]->{'localeDisplayNames'}{'codePatterns'}{'codePattern'}{'language'}{'content'} || $Locales::DB::Language::en::misc_info{'cldr_formats'}{'language'},
+ # # 'locale' => $root[2]->{'localeDisplayNames'}{'localeDisplayPattern'}{'localePattern'} || $Locales::DB::Language::en::misc_info{'cldr_formats'}{'locale'}, # wx_yz has no name but wx does and xy may
+ # # # {'localeDisplayNames'}{'localeDisplayPattern'}{'localePattern'}{'localeSeparator'} => ', ' (not needed since we only use territory subtag)
+ # # },
+ # # 'orientation' => {
+ # # 'characters' => $root[2]->{'layout'}{'orientation'}{'characters'} || $Locales::DB::Language::en::misc_info{'orientation'}{'characters'} || 'left-to-right',
+ # # 'lines' => $root[2]->{'layout'}{'orientation'}{'lines'} || $Locales::DB::Language::en::misc_info{'orientation'}{'lines'} || 'top-to-bottom',
+ # # },
+ # # 'posix' => {
+ # # 'yesstr' => $root[2]->{'posix'}{'messages'}{'yesstr'} || $Locales::DB::Language::en::misc_info{'posix'}{'yesstr'},
+ # # 'nostr' => $root[2]->{'posix'}{'messages'}{'nostr'} || $Locales::DB::Language::en::misc_info{'posix'}{'nostr'},
+ # # # TODO: yesexp/noexp
+ # # },
+ # };
+}
+else {
+ @root = ( \%Locales::DB::Language::en::code_to_name, \%Locales::DB::Territory::en::code_to_name, \%Locales::DB::Language::en::misc_info );
+}
+
+print "Fetching tag $tag\n";
+my ( $lang_code_to_name, $lang_name_to_code, $lang_misc_info, $terr_code_to_name, $terr_name_to_code ) = _locales_build_utils::get_target_structs_from_cldr_for_tag( $tag, @root ) or die "Could not get data for '$tag'";
+
+_locales_build_utils::write_language_module( $tag, $lang_code_to_name, $lang_name_to_code, $lang_misc_info );
+
+_locales_build_utils::write_territory_module( $tag, $terr_code_to_name, $terr_name_to_code );
+
+_locales_build_utils::write_locale_test($tag);
+
+_locales_build_utils::write_get_plural_form_test($tag);
diff --git a/debian/changelog b/debian/changelog
index 7a783c7..1d3b22a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+liblocales-perl (0.34+git20180627.1.d00f65b+ds-1) UNRELEASED; urgency=low
+
+ * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk> Fri, 20 Jan 2023 06:55:20 -0000
+
liblocales-perl (0.34+ds-3) unstable; urgency=medium
[ Debian Janitor ]
Debdiff
File lists identical (after any substitutions)
No differences were encountered in the control files