aboutsummaryrefslogtreecommitdiffstats
path: root/web/index.cgi
blob: 003b51734cc9a646f9f90ddae67e495b086f9e34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
#!/usr/bin/perl -w -I../perllib
#
# index.cgi:
# Main code for FixMyStreet
#
# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org

use strict;
use Standard;
use Utils;
use Encode;
use Error qw(:try);
use File::Slurp;
use LWP::Simple;
use RABX;
use CGI::Carp;
use URI::Escape;

# use Carp::Always;

use CrossSell;
use FixMyStreet::Geocode;
use mySociety::AuthToken;
use mySociety::Config;
use mySociety::DBHandle qw(select_all);
use mySociety::EmailUtil;
use mySociety::Locale;
use mySociety::MaPit;
use mySociety::PostcodeUtil;
use mySociety::Random;
use mySociety::VotingArea;
use mySociety::Web qw(ent NewURL);
use Utils;

sub debug (@) {
    return;
    my ( $format, @args ) = @_;
    warn sprintf $format, map { defined $_ ? $_ : 'undef' } @args;
}

BEGIN {
    if (!dbh()->selectrow_array('select secret from secret for update of secret')) {
        local dbh()->{HandleError};
        dbh()->do('insert into secret (secret) values (?)', {}, unpack('h*', mySociety::Random::random_bytes(32)));
    }
    dbh()->commit();
}

# Main code for index.cgi
sub main {
    my $q = shift;

    if (my $partial = $q->param('partial_token')) {
        # We have a partial token, so fetch data from database and see where we're at.
        my $id = mySociety::AuthToken::retrieve('partial', $partial);
        if ($id) {
            my @row = dbh()->selectrow_array(
                "select latitude, longitude, name, email, title, (photo is not null) as has_photo, phone, detail
                    from problem where id=? and state='partial'", {}, $id);
            if (@row) {
                $q->param('anonymous', 1);
                $q->param('submit_map', 1);
                $q->param('latitude', $row[0]);
                $q->param('longitude', $row[1]);
                $q->param('name', $row[2]);
                $q->param('email', $row[3]);
                $q->param('title', $row[4]);
                $q->param('has_photo', $row[5]);
                $q->param('phone', $row[6]);
                $q->param('detail', $row[7]);
                $q->param('partial', $partial);
            } else {
                my $base = mySociety::Config::get('BASE_URL');
                print $q->redirect(-location => $base . '/report/' . $id);
            }
        }
    }

    my $out = '';
    my %params;
    if ($q->param('submit_problem')) {
        $params{title} = _('Submitting your report');
        ($out) = submit_problem($q);
    } elsif ($q->param('submit_update')) {
        $params{title} = _('Submitting your update');
        ($out) = submit_update($q);
    } elsif ($q->param('submit_map')) {
        ($out, %params) = display_form($q, [], {});
        $params{title} = _('Reporting a problem');
    } elsif ($q->param('id')) {
        ($out, %params) = display_problem($q, [], {});
        $params{title} .= ' - ' . _('Viewing a problem');
    } elsif ($q->param('pc') || ($q->param('x') && $q->param('y')) || ($q->param('lat') || $q->param('lon'))) {
        ($out, %params) = display_location($q);
        $params{title} = _('Viewing a location');
    } elsif ($q->param('e') && $q->param('n')) {
        ($out, %params) = redirect_from_osgb_to_wgs84($q);
    } else {
        ($out, %params) = front_page($q);
    }
    print Page::header($q, %params);
    print $out;
    my %footerparams;
    $footerparams{js} = $params{js} if $params{js};
    $footerparams{template} = $params{template} if $params{template};
    print Page::footer($q, %footerparams);
}
Page::do_fastcgi(\&main);

# Display front page
sub front_page {
    my ($q, $error, $status_code) = @_;
    my $pc_h = ent($q->param('pc') || '');

    # Look up various cobrand things
    my $cobrand = Page::get_cobrand($q);
    my $cobrand_form_elements = Cobrand::form_elements($cobrand, 'postcodeForm', $q);
    my $form_action = Cobrand::url($cobrand, '/', $q);
    my $question = Cobrand::enter_postcode_text($cobrand, $q);
    $question = _("Enter a nearby GB postcode, or street name and area:")
        unless $question;
    my %params = ('context' => 'front-page');
    $params{status_code} = $status_code if $status_code;
    my %vars = (
        error => $error || '',
        pc_h => $pc_h, 
        cobrand_form_elements => $cobrand_form_elements,
        form_action => $form_action,
        question => $question,
    );
    my $cobrand_front_page = Page::template_include('front-page', $q, Page::template_root($q), %vars);
    return ($cobrand_front_page, %params) if $cobrand_front_page;

    my $out = '<p id="expl"><strong>' . _('Report, view, or discuss local problems') . '</strong>';
    my $subhead = _('(like graffiti, fly tipping, broken paving slabs, or street lighting)');
    $out .= '<br><small>' . $subhead . '</small>' if $subhead ne ' ';
    $out .= '</p>';
    #if (my $url = mySociety::Config::get('IPHONE_URL')) {
    #    my $getiphone = _("Get FixMyStreet on your iPhone");
    #    my $new = _("New!");
    #    if ($q->{site} eq 'fixmystreet') {
    #        $out .= <<EOF
#<p align="center" style="margin-bottom:0">
#<img width="23" height="12" alt="$new" src="/i/new.png" border="0">
#<a href="$url">$getiphone</a>
#</p>
#EOF
    #    }
    #}
    $out .= '<p class="error">' . $error . '</p>' if ($error);

    # Add pretty commas for display
    $out .= '<form action="' . $form_action . '" method="get" name="postcodeForm" id="postcodeForm">';
    if (my $token = $q->param('partial')) {
        my $id = mySociety::AuthToken::retrieve('partial', $token);
        if ($id) {
            my $thanks = _("Thanks for uploading your photo. We now need to locate your problem, so please enter a nearby street name or postcode in the box below&nbsp;:");
            $out .= <<EOF;
<p style="margin-top: 0; color: #cc0000;"><img align="right" src="/photo?id=$id" hspace="5">$thanks</p>

<input type="hidden" name="partial_token" value="$token">
EOF
        }
    }
    my $activate = _("Go");
    $out .= <<EOF;
<label for="pc">$question</label>
&nbsp;<input type="text" name="pc" value="$pc_h" id="pc" size="10" maxlength="200">
&nbsp;<input type="submit" value="$activate" id="submit">
$cobrand_form_elements
</form>

<div id="front_intro">
EOF
    $out .= $q->h2(_('How to report a problem'));
    $out .= $q->ol(
        $q->li($question),
        $q->li(_('Locate the problem on a map of the area')),
        $q->li(_('Enter details of the problem')),
        $q->li(_('We send it to the council on your behalf'))
    );

    
    $out .= Cobrand::front_stats(Page::get_cobrand($q), $q);

    $out .= <<EOF;
</div>

EOF

    my $recent_photos = Cobrand::recent_photos(Page::get_cobrand($q), 3);
    my $probs = Cobrand::recent(Page::get_cobrand($q));
    if (@$probs || $recent_photos){
         $out .= '<div id="front_recent">';
         $out .= $q->h2(_('Photos of recent reports')) . $recent_photos if $recent_photos;

         $out .= $q->h2(_('Recently reported problems')) . ' <ul>' if @$probs;
         foreach (@$probs) {
             $out .= '<li><a href="/report/' . $_->{id} . '">'. ent($_->{title});
             $out .= '</a>';
         }
         $out .= '</ul>' if @$probs;
    $out .= '</div>';
    }   

    return ($out, %params);
}

sub submit_update {
    my $q = shift;
    my @vars = qw(id name rznvy update fixed upload_fileid add_alert);
    my %input = map { $_ => $q->param($_) || '' } @vars;
    my @errors;
    my %field_errors;

    my $fh = $q->upload('photo');
    if ($fh) {
        my $err = Page::check_photo($q, $fh);
        push @errors, $err if $err;
    }
    $field_errors{update} = _('Please enter a message') unless $input{update} =~ /\S/;
    $input{name} = undef unless $input{name} =~ /\S/;
    if ($input{rznvy} !~ /\S/) {
        $field_errors{email} = _('Please enter your email');
    } elsif (!mySociety::EmailUtil::is_valid_email($input{rznvy})) {
        $field_errors{email} = _('Please enter a valid email');
    }

    my $image;
    if ($fh) {
        try {
            $image = Page::process_photo($fh);
        } catch Error::Simple with {
            my $e = shift;
            push(@errors, sprintf(_("That image doesn't appear to have uploaded correctly (%s), please try again."), $e));
        };
    }

    if ($input{upload_fileid}) {
        open FP, mySociety::Config::get('UPLOAD_CACHE') . $input{upload_fileid};
        $image = join('', <FP>);
        close FP;
    }

    return display_problem($q, \@errors, \%field_errors) if (@errors || scalar(keys(%field_errors)));
    my $cobrand = Page::get_cobrand($q);
    my $cobrand_data = Cobrand::extra_update_data($cobrand, $q);
    my $id = dbh()->selectrow_array("select nextval('comment_id_seq');");
    Utils::workaround_pg_bytea("insert into comment
        (id, problem_id, name, email, website, text, state, mark_fixed, photo, lang, cobrand, cobrand_data)
        values (?, ?, ?, ?, '', ?, 'unconfirmed', ?, ?, ?, ?, ?)", 7,
        $id, $input{id}, $input{name}, $input{rznvy}, $input{update},
        $input{fixed} ? 't' : 'f', $image, $mySociety::Locale::lang, $cobrand, $cobrand_data);

    my %h = ();
    $h{update} = $input{update};
    $h{name} = $input{name} ? $input{name} : _("Anonymous");
    my $base = Page::base_url_with_lang($q, undef, 1);
    $h{url} = $base . '/C/' . mySociety::AuthToken::store('update', { id => $id, add_alert => $input{add_alert} } );
    dbh()->commit();

    my $out = Page::send_email($q, $input{rznvy}, $input{name}, 'update', %h);
    return $out;
}

sub submit_problem {
    my $q = shift;
    my @vars = qw(council title detail name email phone pc skipped anonymous category partial upload_fileid latitude longitude);
    my %input = map { $_ => scalar $q->param($_) } @vars;
    for (qw(title detail)) {
        $input{$_} = lc $input{$_} if $input{$_} !~ /[a-z]/;
        $input{$_} = ucfirst $input{$_};
        $input{$_} =~ s/\b(dog\s*)shit\b/$1poo/ig;
        $input{$_} =~ s/\b(porta)\s*([ck]abin|loo)\b/[$1ble $2]/ig;
        $input{$_} =~ s/kabin\]/cabin\]/ig;
    }
    my @errors;
    my %field_errors;

    my $cobrand = Page::get_cobrand($q);

    # If in UK and we have a lat,lon coocdinate check it is in UK
    if ( $input{latitude} && mySociety::Config::get('COUNTRY') eq 'GB' ) {
        try {
            Utils::convert_latlon_to_en( $input{latitude}, $input{longitude} );
        } catch Error::Simple with { 
            my $e = shift;
            push @errors, "We had a problem with the supplied co-ordinates - outside the UK?";
        };
    }
    
    my $fh = $q->upload('photo');
    if ($fh) {
        my $err = Page::check_photo($q, $fh);
        $field_errors{photo} = $err if $err;
    }

    $input{council} = 2260 if $q->{site} eq 'scambs'; # All reports go to S. Cambs
    push(@errors, _('No council selected')) unless ($input{council} && $input{council} =~ /^(?:-1|[\d,]+(?:\|[\d,]+)?)$/);
    $field_errors{title} = _('Please enter a subject') unless $input{title} =~ /\S/;
    $field_errors{detail} = _('Please enter some details') unless $input{detail} =~ /\S/;
    if ($input{name} !~ /\S/) {
        $field_errors{name} =  _('Please enter your name');
    } elsif (length($input{name}) < 5 || $input{name} !~ /\s/ || $input{name} =~ /\ba\s*n+on+((y|o)mo?u?s)?(ly)?\b/i) {
        $field_errors{name} = _('Please enter your full name, councils need this information - if you do not wish your name to be shown on the site, untick the box');
    }
    if ($input{email} !~ /\S/) {
        $field_errors{email} = _('Please enter your email');
    } elsif (!mySociety::EmailUtil::is_valid_email($input{email})) {
        $field_errors{email} = _('Please enter a valid email');
    }
    if ($input{category} && $input{category} eq '-- Pick a category --') {
        $field_errors{category} = _('Please choose a category');
        $input{category} = '';
    } elsif ($input{category} && $input{category} eq _('-- Pick a property type --')) {
        $field_errors{category} = _('Please choose a property type');
        $input{category} = '';
    }

    return display_form($q, \@errors, \%field_errors) if (@errors || scalar keys %field_errors); # Short circuit

    my $areas;
    if (defined $input{latitude} && defined $input{longitude}) {
        my $mapit_query = "4326/$input{longitude},$input{latitude}";
        $areas = mySociety::MaPit::call( 'point', $mapit_query );
        if ($input{council} =~ /^[\d,]+(\|[\d,]+)?$/) {
            my $no_details = $1 || '';
            my @area_types = Cobrand::area_types($cobrand);
            my %va = map { $_ => 1 } @area_types;
            my %councils;
            foreach (keys %$areas) {
                $councils{$_} = 1 if $va{$areas->{$_}->{type}};
            }
            my @input_councils = split /,|\|/, $input{council};
            foreach (@input_councils) {
                if (!$councils{$_}) {
                    push(@errors, _('That location is not part of that council'));
                    last;
                }
            }

            if ($no_details) {
                $input{council} =~ s/\Q$no_details\E//;
                @input_councils = split /,/, $input{council};
            }

            # Check category here, won't be present if council is -1
            my @valid_councils = @input_councils;
            if ($input{category} && $q->{site} ne 'emptyhomes') {
                my $categories = select_all("select area_id from contacts
                    where deleted='f' and area_id in ("
                    . $input{council} . ') and category = ?', $input{category});
                $field_errors{category} = _('Please choose a category') unless @$categories;
                @valid_councils = map { $_->{area_id} } @$categories;
                foreach my $c (@valid_councils) {
                    if ($no_details =~ /$c/) {
                        push(@errors, _('We have details for that council'));
                        $no_details =~ s/,?$c//;
                    }
                }
            }
            $input{council} = join(',', @valid_councils) . $no_details;
        }
        $areas = ',' . join(',', sort keys %$areas) . ',';
    } elsif (defined $input{latitude} || defined $input{longitude}) {
        push(@errors, _('Somehow, you only have one co-ordinate. Please try again.'));
    } else {
        push(@errors, _("You haven't specified any sort of co-ordinates. Please try again."));
    }

    my $image;
    if ($fh) {
        try {
            $image = Page::process_photo($fh);
        } catch Error::Simple with {
            my $e = shift;
            $field_errors{photo} = sprintf(_("That image doesn't appear to have uploaded correctly (%s), please try again."), $e);
        };
    }

    if ($input{upload_fileid}) {
        open FP, mySociety::Config::get('UPLOAD_CACHE') . $input{upload_fileid};
        $image = join('', <FP>);
        close FP;
    }

    return display_form($q, \@errors, \%field_errors) if (@errors || scalar keys %field_errors);

    delete $input{council} if $input{council} eq '-1';
    my $used_map = $input{skipped} ? 'f' : 't';
    $input{category} = _('Other') unless $input{category};
    my ($id, $out);
    my $cobrand_data = Cobrand::extra_problem_data($cobrand, $q);
    if (my $token = $input{partial}) {
        my $id = mySociety::AuthToken::retrieve('partial', $token);
        if ($id) {
            dbh()->do("update problem set postcode=?, latitude=?, longitude=?, title=?, detail=?,
                name=?, email=?, phone=?, state='confirmed', council=?, used_map='t',
                anonymous=?, category=?, areas=?, cobrand=?, cobrand_data=?, confirmed=ms_current_timestamp(),
                lastupdate=ms_current_timestamp() where id=?", {}, $input{pc}, $input{latitude}, $input{longitude},
                $input{title}, $input{detail}, $input{name}, $input{email},
                $input{phone}, $input{council}, $input{anonymous} ? 'f' : 't',
                $input{category}, $areas, $cobrand, $cobrand_data, $id);
            Utils::workaround_pg_bytea('update problem set photo=? where id=?', 1, $image, $id)
                if $image;
            dbh()->commit();
            $out = $q->p(sprintf(_('You have successfully confirmed your report and you can now <a href="%s">view it on the site</a>.'), "/report/$id"));
            my $display_advert = Cobrand::allow_crosssell_adverts($cobrand);
            if ($display_advert) {
                $out .= CrossSell::display_advert($q, $input{email}, $input{name});
            }
        } else {
            $out = $q->p('There appears to have been a problem updating the details of your report.
Please <a href="/contact">let us know what went on</a> and we\'ll look into it.');
        }
    } else {
        $id = dbh()->selectrow_array("select nextval('problem_id_seq');");
        Utils::workaround_pg_bytea("insert into problem
            (id, postcode, latitude, longitude, title, detail, name,
             email, phone, photo, state, council, used_map, anonymous, category, areas, lang, cobrand, cobrand_data)
            values
            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'unconfirmed', ?, ?, ?, ?, ?, ?, ?, ?)", 10,
            $id, $input{pc}, $input{latitude}, $input{longitude}, $input{title},
            $input{detail}, $input{name}, $input{email}, $input{phone}, $image,
            $input{council}, $used_map, $input{anonymous} ? 'f': 't', $input{category},
            $areas, $mySociety::Locale::lang, $cobrand, $cobrand_data);
        my %h = ();
        $h{title} = $input{title};
        $h{detail} = $input{detail};
        $h{name} = $input{name};
        my $base = Page::base_url_with_lang($q, undef, 1);
        $h{url} = $base . '/P/' . mySociety::AuthToken::store('problem', $id);
        dbh()->commit();

        $out = Page::send_email($q, $input{email}, $input{name}, 'problem', %h);

    }
    return $out;
}

sub display_form {
    my ($q, $errors, $field_errors) = @_;
    my @errors = @$errors;
    my %field_errors = %{$field_errors};
    my $cobrand = Page::get_cobrand($q);
    push @errors, _('There were problems with your report. Please see below.') if (scalar keys %field_errors);

    my ($pin_x, $pin_y, $pin_tile_x, $pin_tile_y) = (0,0,0,0);
    my @vars = qw(title detail name email phone pc latitude longitude x y skipped council anonymous partial upload_fileid);

    my %input   = ();
    my %input_h = ();

    foreach my $key (@vars) {
        my $val = $q->param($key);
        $input{$key} = defined($val) ? $val : '';   # '0' is valid for longitude
        $input_h{$key} = ent( $input{$key} );
    }

    # Convert lat/lon to easting/northing if given
    # if ($input{lat}) {
    #     try {
    #         ($input{easting}, $input{northing}) = mySociety::GeoUtil::wgs84_to_national_grid($input{lat}, $input{lon}, 'G');
    #         $input_h{easting} = $input{easting};
    #         $input_h{northing} = $input{northing};
    #     } catch Error::Simple with { 
    #         my $e = shift;
    #         push @errors, "We had a problem with the supplied co-ordinates - outside the UK?";
    #     };
    # }

    # Get tile co-ordinates if map clicked
    ($input{x}) = $input{x} =~ /^(\d+)/; $input{x} ||= 0;
    ($input{y}) = $input{y} =~ /^(\d+)/; $input{y} ||= 0;
    my @ps = $q->param;
    foreach (@ps) {
        ($pin_tile_x, $pin_tile_y, $pin_x) = ($1, $2, $q->param($_)) if /^tile_(\d+)\.(\d+)\.x$/;
        $pin_y = $q->param($_) if /\.y$/;
    }

    # We need either a map click, an E/N, to be skipping the map, or be filling in a partial form
    return display_location($q, @errors)
        unless ($pin_x && $pin_y)
            || ($input{latitude} && $input{longitude})
            || ($input{skipped} && $input{pc})
            || ($input{partial} && $input{pc});

    # Work out some co-ordinates from whatever we've got
    my ($latitude, $longitude);
    if ($input{skipped}) {
        # Map is being skipped
        if ( length $input{latitude} && length $input{longitude} ) {
            $latitude  = $input{latitude};
            $longitude = $input{longitude};
        } else {
            my ( $lat, $lon, $error ) =
              FixMyStreet::Geocode::lookup( $input{pc}, $q );
            $latitude  = $lat;
            $longitude = $lon;
        }
    } elsif ($pin_x && $pin_y) {
        # tilma map was clicked on
        ($latitude, $longitude)  = FixMyStreet::Map::click_to_wgs84($pin_tile_x, $pin_x, $pin_tile_y, $pin_y);
    } elsif ( $input{partial} && $input{pc} && !length $input{latitude} && !length $input{longitude} ) {
        my $error;
        try {
            ($latitude, $longitude, $error) = FixMyStreet::Geocode::lookup($input{pc}, $q);
        } catch Error::Simple with {
            $error = shift;
        };
        return FixMyStreet::Geocode::list_choices($error, '/', $q) if ref($error) eq 'ARRAY';
        return front_page($q, $error) if $error;
    } else {
        # Normal form submission
        $latitude  = $input_h{latitude};
        $longitude = $input_h{longitude};
    }

    # Look up councils and do checks for the point we've got
    my @area_types = Cobrand::area_types($cobrand);
    # XXX: I think we want in_gb_locale around the next line, needs testing
    my $all_councils = mySociety::MaPit::call('point', "4326/$longitude,$latitude", type => \@area_types);

    # Let cobrand do a check
    my ($success, $error_msg) = Cobrand::council_check($cobrand, { all_councils => $all_councils }, $q, 'submit_problem');
    if (!$success) {
        return front_page($q, $error_msg);
    }

    if (mySociety::Config::get('COUNTRY') eq 'GB') {
        # Ipswich & St Edmundsbury are responsible for everything in their areas, not Suffolk
        delete $all_councils->{2241} if $all_councils->{2446} || $all_councils->{2443};

        # Norwich is responsible for everything in its areas, not Norfolk
        delete $all_councils->{2233} if $all_councils->{2391};

    } elsif (mySociety::Config::get('COUNTRY') eq 'NO') {

        # Oslo is both a kommune and a fylke, we only want to show it once
        delete $all_councils->{301} if $all_councils->{3};

    }

    return display_location($q, _('That spot does not appear to be covered by a council.
If you have tried to report an issue past the shoreline, for example,
please specify the closest point on land.')) unless %$all_councils;

    # Look up categories for this council or councils
    my $category = '';
    my (%council_ok, @categories);
    my $categories = select_all("select area_id, category from contacts
        where deleted='f' and area_id in (" . join(',', keys %$all_councils) . ')');
    if ($q->{site} ne 'emptyhomes') {
        @$categories = sort { $a->{category} cmp $b->{category} } @$categories;
        foreach (@$categories) {
            $council_ok{$_->{area_id}} = 1;
            next if $_->{category} eq _('Other');
            push @categories, $_->{category};
        }
        if ($q->{site} eq 'scambs') {
            @categories = Page::scambs_categories();
        }
        if (@categories) {
            @categories = ('-- Pick a category --', @categories, _('Other'));
            $category = _('Category:');
        }
    } else {
        foreach (@$categories) {
            $council_ok{$_->{area_id}} = 1;
        }
        @categories = (_('-- Pick a property type --'), _('Empty house or bungalow'),
            _('Empty flat or maisonette'), _('Whole block of empty flats'),
            _('Empty office or other commercial'), _('Empty pub or bar'),
            _('Empty public building - school, hospital, etc.'));
        $category = _('Property type:');
    }
    $category = $q->label({'for'=>'form_category'}, $category) .
        $q->popup_menu(-name=>'category', -values=>\@categories, -id=>'form_category',
            -attributes=>{id=>'form_category'})
        if $category;

    # Work out what help text to show, depending on whether we have council details
    my @councils = keys %council_ok;
    my $details;
    if (@councils == scalar keys %$all_councils) {
        $details = 'all';
    } elsif (@councils == 0) {
        $details = 'none';
    } else {
        $details = 'some';
    }

    # Forms that allow photos need a different enctype
    my $allow_photo_upload = Cobrand::allow_photo_upload($cobrand);
    my $enctype = '';
    if ($allow_photo_upload) {
         $enctype = ' enctype="multipart/form-data"';
    }

    my %vars;
    $vars{input_h} = \%input_h;
    $vars{field_errors} = \%field_errors;
    if ($input{skipped}) {
       my $cobrand_form_elements = Cobrand::form_elements($cobrand, 'mapSkippedForm', $q);
       my $form_action = Cobrand::url($cobrand, '/', $q); 
       $vars{form_start} = <<EOF;
<form action="$form_action" method="post" name="mapSkippedForm"$enctype>
<input type="hidden" name="pc" value="$input_h{pc}">
<input type="hidden" name="skipped" value="1">
$cobrand_form_elements
<div id="skipped-map">
EOF
    } else {
        my $type;
        if ($allow_photo_upload) {
            $type = 2;
        } else {
            $type = 1;
        }
        $vars{form_start} = FixMyStreet::Map::display_map($q,
            latitude => $latitude, longitude => $longitude,
            type => $type,
            pins => [ [ $latitude, $longitude, 'purple' ] ],
        );
        my $partial_id;
        if (my $token = $input{partial}) {
            $partial_id = mySociety::AuthToken::retrieve('partial', $token);
            if ($partial_id) {
                $vars{form_start} .= $q->p({id=>'unknown'}, 'Please note your report has
                <strong>not yet been sent</strong>. Choose a category
                and add further information below, then submit.');
            }
        }
        $vars{text_located} = $q->p(_('You have located the problem at the point marked with a purple pin on the map.
If this is not the correct location, simply click on the map again. '));
    }
    $vars{page_heading} = $q->h1(_('Reporting a problem'));

    if ($details eq 'all') {
        my $council_list = join('</strong> or <strong>', map { encode_utf8($_->{name}) } values %$all_councils);
        if ($q->{site} eq 'emptyhomes'){
            $vars{text_help} = '<p>' . sprintf(_('All the information you provide here will be sent to <strong>%s</strong>.
On the site, we will show the subject and details of the problem, plus your
name if you give us permission.'), $council_list);
        } else {
            $vars{text_help} = '<p>' . sprintf(_('All the information you provide here will be sent to <strong>%s</strong>.
The subject and details of the problem will be public, plus your
name if you give us permission.'), $council_list);
        }
        $vars{text_help} .= '<input type="hidden" name="council" value="' . join(',', keys %$all_councils) . '">';
    } elsif ($details eq 'some') {
        my $e = Cobrand::contact_email($cobrand);
        my %councils = map { $_ => 1 } @councils;
        my @missing;
        foreach (keys %$all_councils) {
            push @missing, $_ unless $councils{$_};
        }
        my $n = @missing;
        my $list = join(_(' or '), map { encode_utf8($all_councils->{$_}->{name}) } @missing);
        $vars{text_help} = '<p>' . _('All the information you provide here will be sent to') . '<strong>'
            . join('</strong>' . _(' or ') . '<strong>', map { encode_utf8($all_councils->{$_}->{name}) } @councils)
            . '</strong>. ';
        $vars{text_help} .= _('The subject and details of the problem will be public, plus your name if you give us permission.');
        $vars{text_help} .= mySociety::Locale::nget(
            _('We do <strong>not</strong> yet have details for the other council that covers this location.'),
            _('We do <strong>not</strong> yet have details for the other councils that cover this location.'),
            $n
        );
        $vars{text_help} .=  ' ' . sprintf(_("You can help us by finding a contact email address for local problems for %s and emailing it to us at <a href='mailto:%s'>%s</a>."), $list, $e, $e);
        $vars{text_help} .= '<input type="hidden" name="council" value="' . join(',', @councils)
            . '|' . join(',', @missing) . '">';
    } else {
        my $e = Cobrand::contact_email($cobrand);
        my $list = join(' or ', map { encode_utf8($_->{name}) } values %$all_councils);
        my $n = scalar keys %$all_councils;
        if ($q->{site} ne 'emptyhomes') {
            $vars{text_help} = '<p>';
            $vars{text_help} .= mySociety::Locale::nget(
                _('We do not yet have details for the council that covers this location.'),
                _('We do not yet have details for the councils that cover this location.'),
                $n
            );
            $vars{text_help} .= _("If you submit a problem here the subject and details of the problem will be public, but the problem will <strong>not</strong> be reported to the council.");
            $vars{text_help} .= sprintf(_("You can help us by finding a contact email address for local problems for %s and emailing it to us at <a href='mailto:%s'>%s</a>."), $list, $e, $e);
        } else {
            $vars{text_help} = _("<p>We do not yet have details for the council that covers this location. If you submit a report here it will be left on the site, but not reported to the council &ndash; please still leave your report, so that we can show to the council the activity in their area.");
        }
        $vars{text_help} .= '<input type="hidden" name="council" value="-1">';
    }

    if ($input{skipped}) {
        $vars{text_help} .= $q->p(_('Please fill in the form below with details of the problem,
and describe the location as precisely as possible in the details box.'));
    } elsif ($q->{site} eq 'scambs') {
        $vars{text_help} .= '<p>Please fill in details of the problem below. We won\'t be able
to help unless you leave as much detail as you can, so please describe the exact location of
the problem (e.g. on a wall), what it is, how long it has been there, a description (and a
photo of the problem if you have one), etc.';
    } elsif ($q->{site} eq 'emptyhomes') {
        $vars{text_help} .= $q->p(_(<<EOF));
Please fill in details of the empty property below, saying what type of
property it is e.g. an empty home, block of flats, office etc. Tell us
something about its condition and any other information you feel is relevant.
There is no need for you to give the exact address. Please be polite, concise
and to the point; writing your message entirely in block capitals makes it hard
to read, as does a lack of punctuation.
EOF
    } elsif ($details ne 'none') {
        $vars{text_help} .= $q->p(_('Please fill in details of the problem below. The council won\'t be able
to help unless you leave as much detail as you can, so please describe the exact location of
the problem (e.g. on a wall), what it is, how long it has been there, a description (and a
photo of the problem if you have one), etc.'));
    } else {
        $vars{text_help} .= $q->p(_('Please fill in details of the problem below.'));
    }

    $vars{text_help} .= '
<input type="hidden" name="latitude" value="' . $latitude . '">
<input type="hidden" name="longitude" value="' . $longitude . '">';

    if (@errors) {
        $vars{errors} = '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>';
    }

    $vars{anon} = ($input{anonymous}) ? ' checked' : ($input{title} ? '' : ' checked');

    $vars{form_heading} = $q->h2(_('Empty property details form')) if $q->{site} eq 'emptyhomes';
    $vars{subject_label} = _('Subject:');
    $vars{detail_label} = _('Details:');
    $vars{photo_label} = _('Photo:');
    $vars{name_label} = _('Name:');
    $vars{email_label} = _('Email:');
    $vars{phone_label} = _('Phone:');
    $vars{optional} = _('(optional)');
    if ($q->{site} eq 'emptyhomes') {
        $vars{anonymous} = _('Can we show your name on the site?');
    } else {
        $vars{anonymous} = _('Can we show your name publicly?');
    }
    $vars{anonymous2} = _('(we never show your email address or phone number)');

    my $partial_id;
    if (my $token = $input{partial}) {
        $partial_id = mySociety::AuthToken::retrieve('partial', $token);
        if ($partial_id) {
            $vars{partial_field} = '<input type="hidden" name="partial" value="' . $token . '">';
            $vars{partial_field} .= '<input type="hidden" name="has_photo" value="' . $q->param('has_photo') . '">';
        }
    }
    my $photo_input = ''; 
    if ($allow_photo_upload) {
         $photo_input = <<EOF;
<div id="fileupload_normalUI">
<label for="form_photo">$vars{photo_label}</label>
<input type="file" name="photo" id="form_photo">
</div>
EOF
    }
    if ($partial_id && $q->param('has_photo')) {
        $vars{photo_field} = "<p>The photo you uploaded was:</p> <p><img src='/photo?id=$partial_id'></p>";
    } else {
        $vars{photo_field} = $photo_input;
    }

    if ($q->{site} ne 'emptyhomes') {
        $vars{text_notes} =
            $q->p(_("Please note:")) .
            "<ul>" .
            $q->li(_("We will only use your personal information in accordance with our <a href=\"/faq#privacy\">privacy policy.</a>")) .
            $q->li(_("Please be polite, concise and to the point.")) .
            $q->li(_("Please do not be abusive &mdash; abusing your council devalues the service for all users.")) .
            $q->li(_("Writing your message entirely in block capitals makes it hard to read, as does a lack of punctuation.")) .
            $q->li(_("Remember that FixMyStreet is primarily for reporting physical problems that can be fixed. If your problem is not appropriate for submission via this site remember that you can contact your council directly using their own website."));
        $vars{text_notes} .=
            $q->li(_("FixMyStreet and the Guardian are providing this service in partnership in <a href=\"/faq#privacy\">certain cities</a>. In those cities, both have access to any information submitted, including names and email addresses, and will use it only to ensure the smooth running of the service, in accordance with their privacy policies."))
            if mySociety::Config::get('COUNTRY') eq 'GB';
        $vars{text_notes} .= "</ul>\n";
    }

    %vars = (%vars, 
        category => $category,
        map_end => FixMyStreet::Map::display_map_end(1),
        url_home => Cobrand::url($cobrand, '/', $q),
        submit_button => _('Submit')
    );
    return (Page::template_include('report-form', $q, Page::template_root($q), %vars), robots => 'noindex,nofollow');
}

# redirect from osgb
sub redirect_from_osgb_to_wgs84 {
    my ($q) = @_;

    my $e = $q->param('e');
    my $n = $q->param('n');

    my ( $lat, $lon ) = Utils::convert_en_to_latlon_truncated( $e, $n );

    my $lat_lon_url = NewURL(
        $q,
        -retain => 1,
        e       => undef,
        n       => undef,
        lat     => $lat,
        lon     => $lon
    );

    print $q->redirect(
        -location => $lat_lon_url,
        -status   => 301,            # permanent
    );

    return '';
}

sub display_location {
    my ($q, @errors) = @_;
    my $cobrand = Page::get_cobrand($q);
    my @vars = qw(pc x y lat lon all_pins no_pins);

    my %input   = ();
    my %input_h = ();

    foreach my $key (@vars) {
        my $val = $q->param($key);
        $input{$key} = defined($val) ? $val : '';   # '0' is valid for longitude
        $input_h{$key} = ent( $input{$key} );
    }

    my $latitude  = $input{lat};
    my $longitude = $input{lon};

    # X/Y referring to tiles old-school
    (my $x) = $input{x} =~ /^(\d+)/; $x ||= 0;
    (my $y) = $input{y} =~ /^(\d+)/; $y ||= 0;

    return front_page( $q, @errors )
      unless ( $x && $y )
      || $input{pc}
      || ( defined $latitude && defined $longitude );

    if ( $x && $y ) {

        # Convert the tile co-ordinates to real ones.
        ( $latitude, $longitude ) =
          FixMyStreet::Map::tile_xy_to_wgs84( $x, $y );
    }
    elsif ( $latitude && $longitude ) {

        # Don't need to do anything
    }
    else {
        my $error;
        try {
            ( $latitude, $longitude, $error ) =
              FixMyStreet::Geocode::lookup( $input{pc}, $q );

            debug 'Looked up postcode "%s": lat: "%s", lon: "%s", error: "%s"',
              $input{pc}, $latitude, $longitude, $error;
        }
        catch Error::Simple with {
            $error = shift;
        };
        return FixMyStreet::Geocode::list_choices( $error, '/', $q )
          if ( ref($error) eq 'ARRAY' );
        return front_page( $q, $error ) if $error;
    }

    # Check this location is okay to be displayed for the cobrand
    my ($success, $error_msg) = Cobrand::council_check($cobrand, { lat => $latitude, lon => $longitude }, $q, 'display_location');
    return front_page($q, $error_msg) unless $success;

    # Deal with pin hiding/age
    my ($hide_link, $hide_text, $all_link, $all_text, $interval);
    if ($input{all_pins}) {
        $all_link = NewURL($q, -retain=>1, no_pins=>undef, all_pins=>undef);
        $all_text = _('Hide stale reports');
    } else {
        $all_link = NewURL($q, -retain=>1, no_pins=>undef, all_pins=>1);
        $all_text = _('Include stale reports');
        $interval = '6 months';
    }   

    my ($on_map_all, $on_map, $around_map, $dist) = FixMyStreet::Map::map_features($q, $latitude, $longitude, $interval);
    my @pins;
    foreach (@$on_map_all) {
        push @pins, [ $_->{latitude}, $_->{longitude}, ($_->{state} eq 'fixed' ? 'green' : 'red'), $_->{id} ];
    }
    my $on_list = '';
    foreach (@$on_map) {
        my $report_url = NewURL($q, -retain => 1, -url => '/report/' . $_->{id}, pc => undef, x => undef, 'y' => undef);
        $report_url = Cobrand::url($cobrand, $report_url, $q);  
        $on_list .= '<li><a href="' . $report_url . '">';
        $on_list .= ent($_->{title}) . '</a> <small>(';
        $on_list .= Page::prettify_epoch($q, $_->{time}, 1) . ')</small>';
        $on_list .= ' <small>' . _('(fixed)') . '</small>' if $_->{state} eq 'fixed';
        $on_list .= '</li>';
    }
    $on_list = $q->li(_('No problems have been reported yet.'))
        unless $on_list;

    my $around_list = '';
    foreach (@$around_map) {
        my $report_url = Cobrand::url($cobrand, NewURL($q, -retain => 1, -url => '/report/' . $_->{id}, pc => undef, x => undef, 'y' => undef), $q);  
        $around_list .= '<li><a href="' . $report_url . '">';
        my $dist = int($_->{distance}*10+0.5);
        $dist = $dist / 10;
        $around_list .= ent($_->{title}) . '</a> <small>(';
        $around_list .= Page::prettify_epoch($q, $_->{time}, 1) . ', ';
        $around_list .= $dist . 'km)</small>';
        $around_list .= ' <small>' . _('(fixed)') . '</small>' if $_->{state} eq 'fixed';
        $around_list .= '</li>';
        push @pins, [ $_->{latitude}, $_->{longitude}, ($_->{state} eq 'fixed' ? 'green' : 'red'), $_->{id} ];
    }
    $around_list = $q->li(_('No problems found.'))
        unless $around_list;

    if ($input{no_pins}) {
        $hide_link = NewURL($q, -retain=>1, no_pins=>undef);
        $hide_text = _('Show pins');
        @pins = ();
    } else {
        $hide_link = NewURL($q, -retain=>1, no_pins=>1);
        $hide_text = _('Hide pins');
    }
    my $map_links = "<p id='sub_map_links'><a id='hide_pins_link' rel='nofollow' href='$hide_link'>$hide_text</a> | <a id='all_pins_link' rel='nofollow' href='$all_link'>$all_text</a></p> <input type='hidden' id='all_pins' name='all_pins' value='$input_h{all_pins}'>";

    # truncate the lat,lon for nicer rss urls
    my ( $short_lat, $short_lon ) =
      map { Utils::truncate_coordinate($_) }    #
      ( $latitude, $longitude );    
    
    my $url_skip = NewURL($q, -retain=>1, pc => undef,
        x => undef, 'y' => undef,
        latitude => $short_lat, longitude => $short_lon,
        'submit_map'=>1, skipped=>1
    );
    my $pc_h = ent($q->param('pc') || '');
    
    my %vars = (
        'map' => FixMyStreet::Map::display_map($q,
            latitude => $latitude, longitude => $longitude,
            type => 1,
            pins => \@pins,
            post => $map_links
        ),
        map_end => FixMyStreet::Map::display_map_end(1),
        url_home => Cobrand::url($cobrand, '/', $q),
        url_rss => Cobrand::url($cobrand, NewURL($q, -retain => 1, -url=> "/rss/l/$short_lat,$short_lon", pc => undef, x => undef, y => undef, lat => undef, lon => undef ), $q),
        url_email => Cobrand::url($cobrand, NewURL($q, -retain => 1, pc => undef, lat => $short_lat, lon => $short_lon, -url=>'/alert', feed=>"local:$short_lat:$short_lon"), $q),
        url_skip => $url_skip,
        email_me => _('Email me new local problems'),
        rss_alt => _('RSS feed'),
        rss_title => _('RSS feed of recent local problems'),
        reports_on_around => $on_list,
        reports_nearby => $around_list,
        heading_problems => _('Problems in this area'),
        heading_on_around => _('Reports on and around the map'),
        heading_closest => sprintf(_('Closest nearby problems <small>(within&nbsp;%skm)</small>'), $dist),
        distance => $dist,
        pc_h => $pc_h,
        errors => @errors ? '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>' : '',
        text_to_report => _('To report a problem, simply
        <strong>click on the map</strong> at the correct location.'),
        text_skip => sprintf(_("<small>If you cannot see the map, <a href='%s' rel='nofollow'>skip this
        step</a>.</small>"), $url_skip),
    );

    my %params = (
        rss => [ _('Recent local problems, FixMyStreet'), "/rss/l/$short_lat,$short_lon" ],
        robots => 'noindex,nofollow',
    );

    return (Page::template_include('map', $q, Page::template_root($q), %vars), %params);
}

sub display_problem {
    my ($q, $errors, $field_errors) = @_;
    my @errors = @$errors;
    my %field_errors = %{$field_errors};
    my $cobrand = Page::get_cobrand($q);
    push @errors, _('There were problems with your update. Please see below.') if (scalar keys %field_errors);

    my @vars = qw(id name rznvy update fixed add_alert upload_fileid submit_update);
    my %input = map { $_ => $q->param($_) || '' } @vars;
    my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars;
    my $base = Cobrand::base_url($cobrand);

    # Some council with bad email software
    if ($input{id} =~ /^3D\d+$/) {
        $input{id} =~ s/^3D//;
        print $q->redirect(-location => $base . '/report/' . $input{id}, -status => 301);
        return '';
    }

    # Redirect old /?id=NNN URLs to /report/NNN
    if (!@errors && !scalar keys %field_errors && $ENV{SCRIPT_URL} eq '/') {
        print $q->redirect(-location => $base . '/report/' . $input{id}, -status => 301);
        return '';
    }

    # Get all information from database
    return display_location($q, _('Unknown problem ID')) if !$input{id} || $input{id} =~ /\D/;
    my $problem = Problems::fetch_problem($input{id});
    return display_location($q, _('Unknown problem ID')) unless $problem;
    return front_page($q, _('That report has been removed from FixMyStreet.'), '410 Gone') if $problem->{state} eq 'hidden';

    my $extra_data = Cobrand::extra_data($cobrand, $q);
    my $google_link = Cobrand::base_url_for_emails($cobrand, $extra_data)
        . '/report/' . $problem->{id};

    # truncate the lat,lon for nicer rss urls
    my ( $short_lat, $short_lon ) =
      map { Utils::truncate_coordinate($_) }    #
      ( $problem->{latitude}, $problem->{longitude} );

    my $map_links = '';
    $map_links = "<p id='sub_map_links'>"
      . "<a href=\"http://maps.google.co.uk/maps?output=embed&amp;z=16&amp;q="
      . URI::Escape::uri_escape_utf8( $problem->{title} . ' - ' . $google_link )
      . "\@$short_lat,$short_lon\">View on Google Maps</a></p>"
        if mySociety::Config::get('COUNTRY') eq 'GB';

    my $banner;
    if ($q->{site} ne 'emptyhomes' && $problem->{state} eq 'confirmed' && $problem->{duration} > 8*7*24*60*60) {
        $banner = $q->p({id => 'unknown'}, _('This problem is old and of unknown status.'));
    }
    if ($problem->{state} eq 'fixed') {
        $banner = $q->p({id => 'fixed'}, _('This problem has been fixed') . '.');
    }

    my $contact_url = Cobrand::url($cobrand, NewURL($q, -retain => 1, pc => undef, x => undef, 'y' => undef, -url=>'/contact?id=' . $input{id}), $q);
    my $back = Cobrand::url($cobrand, NewURL($q, -url => '/',
        lat => $short_lat, lon => $short_lon,
        -retain => 1, pc => undef, x => undef, 'y' => undef, id => undef
    ), $q);
    my $fixed = ($input{fixed}) ? ' checked' : '';

    my %vars = (
        banner => $banner,
        map_start => FixMyStreet::Map::display_map($q,
            latitude => $problem->{latitude}, longitude => $problem->{longitude},
            type => 0,
            pins => [ [ $problem->{latitude}, $problem->{longitude}, 'blue' ] ],
            post => $map_links
        ),
        map_end => FixMyStreet::Map::display_map_end(0),
        problem_title => ent($problem->{title}),
        problem_meta => Page::display_problem_meta_line($q, $problem),
        problem_detail => Page::display_problem_detail($problem),
        problem_photo => Page::display_problem_photo($q, $problem),
        problem_updates => Page::display_problem_updates($input{id}, $q),
        unsuitable => $q->a({rel => 'nofollow', href => $contact_url}, _('Offensive? Unsuitable? Tell us')),
        more_problems => '<a href="' . $back . '">' . _('More problems nearby') . '</a>',
        url_home => Cobrand::url($cobrand, '/', $q),
        alert_link => Cobrand::url($cobrand, NewURL($q, -url => '/alert?type=updates;id='.$input_h{id}, -retain => 1, pc => undef, x => undef, 'y' => undef ), $q),
        alert_text => _('Email me updates'),
        email_label => _('Email:'),
        subscribe => _('Subscribe'),
        blurb => _('Receive email when updates are left on this problem'),
        cobrand_form_elements1 => Cobrand::form_elements($cobrand, 'alerts', $q),
        form_alert_action => Cobrand::url($cobrand, '/alert', $q),
        rss_url => Cobrand::url($cobrand,  NewURL($q, -retain=>1, -url => '/rss/'.$input_h{id}, pc => undef, x => undef, 'y' => undef, id => undef), $q),
        rss_title => _('RSS feed'),
        rss_alt => _('RSS feed of updates to this problem'),
        update_heading => $q->h2(_('Provide an update')),
        field_errors => \%field_errors,
        add_alert_checked => ($input{add_alert} || !$input{submit_update}) ? ' checked' : '',
        fixedline_box => $problem->{state} eq 'fixed' ? '' : qq{<input type="checkbox" name="fixed" id="form_fixed" value="1"$fixed>},
        fixedline_label => $problem->{state} eq 'fixed' ? '' : qq{<label for="form_fixed">} . _('This problem has been fixed') . qq{</label>},
        name_label => _('Name:'),
        update_label => _('Update:'),
        alert_label => _('Alert me to future updates'),
        post_label => _('Post'),
        cobrand_form_elements => Cobrand::form_elements($cobrand, 'updateForm', $q),
        form_action => Cobrand::url($cobrand, '/', $q),
        input_h => \%input_h,
        optional => _('(optional)'),
    );

    $vars{update_blurb} = $q->p($q->small(_('Please note that updates are not sent to the council. If you leave your name it will be public. Your information will only be used in accordance with our <a href="/faq#privacy">privacy policy</a>')))
        unless $q->{site} eq 'emptyhomes'; # No council blurb

    if (@errors) {
        $vars{errors} = '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>';
    }
    
    my $allow_photo_upload = Cobrand::allow_photo_upload($cobrand);
    if ($allow_photo_upload) {
        my $photo_label = _('Photo:');
        $vars{enctype} = ' enctype="multipart/form-data"';
        $vars{photo_element} = <<EOF;
<div id="fileupload_normalUI">
<label for="form_photo">$photo_label</label>
<input type="file" name="photo" id="form_photo">
</div>
EOF
    }
 
    my %params = (
        rss => [ _('Updates to this problem, FixMyStreet'), "/rss/$input_h{id}" ],
        robots => 'index, nofollow',
        title => $problem->{title}
    );

    my $page = Page::template_include('problem', $q, Page::template_root($q), %vars);
    return ($page, %params);
}
or the law tell us to." msgstr "" "No revelaremos tu dirección de correo a nadie salvo que tú\n" "nos lo digas, o la ley nos obligue." msgid "We will not reveal your email addresses to anybody unless you\\nor the law tell us to." msgstr "" "No revelaremos tu dirección de correo a nadie salvo que tú\n" "nos lo digas, o la ley nos obligue." msgid "We're waiting for" msgstr "Estamos esperando a que " msgid "We're waiting for someone to read" msgstr "Estamos esperando a que alguien lea" msgid "We've sent an email to your new email address. You'll need to click the link in\\nit before your email address will be changed." msgstr "" "Hemos enviado un correo a tu nueva dirección de correo. Necesitarás seguir el enlace\n" "incluido en él para que se actualice tu dirección de correo." msgid "We've sent you an email, and you'll need to click the link in it before you can\\ncontinue." msgstr "" "Te hemos enviado un correo, necesitarás seguir el enlace incluído en él antes\n" "de continuar." msgid "We've sent you an email, click the link in it, then you can change your password." msgstr "Te hemos enviado un correo, sigue el enlace incluído en él, y podrás cambiar tu contraseña." msgid "What are you doing?" msgstr "¿Qué está haciendo?" msgid "What best describes the status of this request now?" msgstr "¿Cómo describirías el estado de esta solicitud ahora?" msgid "What information has been released?" msgstr "¿Qué información se ha solicitado?" msgid "What information has been requested?" msgstr "¿Qué información ha sido solicitada?" msgid "When you get there, please update the status to say if the response \\ncontains any useful information." msgstr "" "Por favor actualiza el estado para indicar si la respuesta \n" "contiene información útil." msgid "When you receive the paper response, please help\\n others find out what it says:" msgstr "" "Cuando reciba la respuesta en papel, por favor ayude\n" " a que otros sepan lo que dice:" msgid "When you're done, <strong>come back here</strong>, <a href=\"{{url}}\">reload this page</a> and file your new request." msgstr "Cuando esté listo, <strong>vuelva aquí</strong>, <a href=\"{{url}}\">recargue esta página</a> y cree una nueva solicitud." msgid "Which of these is happening?" msgstr "¿Qué está pasando?" msgid "Who can I request information from?" msgstr "¿A quién puedo solicitar información?" msgid "Why specifically do you consider this request unsuitable?" msgstr "" msgid "Withdrawn by the requester." msgstr "Retirada por el autor." msgid "Wk" msgstr "Wk" msgid "Would you like to see a website like this in your country?" msgstr "¿Te gustaría ver una web como esta en tu país?" msgid "Write a reply" msgstr "Escribe una respuesta" msgid "Write a reply to " msgstr "Escribir una respuesta a " msgid "Write your FOI follow up message to " msgstr "Escribe tu respuesta a " msgid "Write your request in <strong>simple, precise language</strong>." msgstr "Escribe tu solicitud en un <strong>lenguaje sencillo y claro</strong>." msgid "You" msgstr "Tú" msgid "You already created the same batch of requests on {{date}}. You can either view the <a href=\"{{existing_batch}}\">existing batch</a>, or edit the details below to make a new but similar batch of requests." msgstr "" msgid "You are already following new requests" msgstr "Tu ya estas siguiendo nuevos pedidos" msgid "You are already following requests to {{public_body_name}}" msgstr "Tu ya estas siguiendo pedidos a {{public_body_name}}" msgid "You are already following things matching this search" msgstr "Ya estás siguiendo esta búsqueda por correo" msgid "You are already following this person" msgstr "Ya estás siguiendo a esta persona por correo" msgid "You are already following this request" msgstr "Ya estás siguiendo esta solicitud por correo" msgid "You are already subscribed to '{{link_to_authority}}', a public authority." msgstr "" msgid "You are already subscribed to '{{link_to_request}}', a request." msgstr "" msgid "You are already subscribed to '{{link_to_user}}', a person." msgstr "" msgid "You are already subscribed to <a href=\"{{search_url}}\">this search</a>." msgstr "" msgid "You are already subscribed to any <a href=\"{{new_requests_url}}\">new requests</a>." msgstr "" msgid "You are already subscribed to any <a href=\"{{successful_requests_url}}\">successful requests</a>." msgstr "" msgid "You are currently receiving notification of new activity on your wall by email." msgstr "Actualmente estas recibiendo notificaciones de nueva actividad en tu muro por correo electronico." msgid "You are following all new successful responses" msgstr "Estás recibiendo correos sobre cualquier nueva respuesta exitosa" msgid "You are no longer following '{{link_to_authority}}', a public authority." msgstr "" msgid "You are no longer following '{{link_to_request}}', a request." msgstr "" msgid "You are no longer following '{{link_to_user}}', a person." msgstr "" msgid "You are no longer following <a href=\"{{new_requests_url}}\">new requests</a>." msgstr "" msgid "You are no longer following <a href=\"{{search_url}}\">this search</a>." msgstr "" msgid "You are no longer following <a href=\"{{successful_requests_url}}\">successful requests</a>." msgstr "" msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about '{{link_to_authority}}', a public authority." msgstr "" msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about '{{link_to_request}}', a request." msgstr "" msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about '{{link_to_user}}', a person." msgstr "" msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about <a href=\"{{new_requests_url}}\">new requests</a>." msgstr "" msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about <a href=\"{{search_url}}\">this search</a>." msgstr "" msgid "You are now <a href=\"{{wall_url_user}}\">following</a> updates about <a href=\"{{successful_requests_url}}\">successful requests</a>." msgstr "" msgid "You can <strong>complain</strong> by" msgstr "Puede <strong>apelar</strong>" msgid "You can change the requests and users you are following on <a href=\"{{profile_url}}\">your profile page</a>." msgstr "Puedes cambiar los pedidos y usuarios a los que estas siguiendo en <a href=\"{{profile_url}}\">tu página de perfil</a>." msgid "You can get this page in computer-readable format as part of the main JSON\\npage for the request. See the <a href=\"{{api_path}}\">API documentation</a>." msgstr "" "Puedes obtener esta página en un formato procesable como parte de la página JSON\n" "de la solicitud. Consulte <a href=\"{{api_path}}\">la documentación de nuestro API</a>." msgid "You can only request information about the environment from this authority." msgstr "Solo puede solicitar información medioambiental a esta institución" msgid "You have a new response to the {{law_used_full}} request " msgstr "Tienes una nueva respuesta a la solicitud {{law_used_full}} " msgid "You have found a bug. Please <a href=\"{{contact_url}}\">contact us</a> to tell us about the problem" msgstr "Ha encontrado un error. Por favor <a href=\"{{contact_url}}\">contáctenos</a> para informarnos del problema" msgid "You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}." msgstr "Has alcanzado el límite de solicitudes en un día, que es de {{max_requests_per_user_per_day}} solicitudes en un plazo de 24 horas. Podrás enviar una nueva solicitud en {{can_make_another_request}}." msgid "You have made no Freedom of Information requests using this site." msgstr "No ha realizado solicitudes de información usando esta web." msgid "You have now changed the text about you on your profile." msgstr "Has cambiado el texto sobre ti en tu perfil." msgid "You have now changed your email address used on {{site_name}}" msgstr "Ha cambiado la dirección de correo que usa en {{site_name}}" msgid "You just tried to sign up to {{site_name}}, when you\\nalready have an account. Your name and password have been\\nleft as they previously were.\\n\\nPlease click on the link below." msgstr "" "Has intentado registrarte en {{site_name}}, pero\n" "ya tienes una cuenta. Tu nombre y contraseña no se han\n" "modificado.\n" "\n" "Por favor usa el siguiente enlace para continuar." msgid "You know what caused the error, and can <strong>suggest a solution</strong>, such as a working email address." msgstr "Sabes lo que ha causado el error, y puedes <strong>sugerir una solución</a>, como una dirección de correo válida." msgid "You may <strong>include attachments</strong>. If you would like to attach a\\n file too large for email, use the form below." msgstr "Puede <strong>adjuntar ficheros</strong>. Si quiere adjuntar un fichero demasiado grande para el correo, puede utilizar el siguiente formulario." msgid "You may be able to find one on their website, or by phoning them up and asking. If you manage to find one, then please send it to us:" msgstr "" msgid "You may be able to find\\n one on their website, or by phoning them up and asking. If you manage\\n to find one, then please <a href=\"{{url}}\">send it to us</a>." msgstr "" "Puede que encuentres una\n" " en su página web, o preguntando por teléfono. Si la consigues\n" " por favor <a href=\"{{url}}\">envíanosla</a>." msgid "You may be able to find\\none on their website, or by phoning them up and asking. If you manage\\nto find one, then please <a href=\"{{help_url}}\">send it to us</a>." msgstr "" "Puede que encuentres una\n" "en su página web, o llamándoles para preguntar. Si\n" "consigues una, por favor <a href=\"{{help_url}}\">mándanosla</a>." msgid "You need to be logged in to change the text about you on your profile." msgstr "Necesitas identificarte para cambiar el texto de tu perfil." msgid "You need to be logged in to change your profile photo." msgstr "Necesitas identificarte para cambiar la foto de tu perfil." msgid "You need to be logged in to clear your profile photo." msgstr "Necesitas identificarte para borrar la foto de tu perfil." msgid "You need to be logged in to edit your profile." msgstr "Tienes que loguearte para poder editar tu perfil." msgid "You need to be logged in to report a request for administrator attention" msgstr "Necesitas abrir una sesión para alertar a los moderadores sobre esta solicitud" msgid "You previously submitted that exact follow up message for this request." msgstr "Ya has enviado esa misma respuesta a esta solicitud." msgid "You should have received a copy of the request by email, and you can respond\\n by <strong>simply replying</strong> to that email. For your convenience, here is the address:" msgstr "" "Debería de haber recibido una copia de la petición por correo electrónico, y puede contestar\n" "<strong>simplemente respondiendo</strong> a ese correo. Para su comodidad, esta es la dirección:" msgid "You want to <strong>give your postal address</strong> to the authority in private." msgstr "Quieres <strong>darle tu dirección postal</strong> al organismo en privado." msgid "You will be unable to make new requests, send follow ups, add annotations or\\nsend messages to other users. You may continue to view other requests, and set\\nup\\nemail alerts." msgstr "" "No podrás realizar nuevas solicitudes, enviar respuestas, añadir comentarios o\n" "contactar con otros usuarios. Podrás continuar viendo otras solicitudes y\n" "configurando nuevas alertas de correo." msgid "You will no longer be emailed updates for those alerts" msgstr "Ya no recibirá correos para esas alertas" msgid "You will now be emailed updates about '{{link_to_authority}}', a public authority." msgstr "" msgid "You will now be emailed updates about '{{link_to_request}}', a request." msgstr "" msgid "You will now be emailed updates about '{{link_to_user}}', a person." msgstr "" msgid "You will now be emailed updates about <a href=\"{{search_url}}\">this search</a>." msgstr "" msgid "You will now be emailed updates about <a href=\"{{successful_requests_url}}\">successful requests</a>." msgstr "" msgid "You will now be emailed updates about any <a href=\"{{new_requests_url}}\">new requests</a>." msgstr "" msgid "You will only get an answer to your request if you follow up\\nwith the clarification." msgstr "" "Sólo recibirás una respuesta a tu solicitud si continúas\n" "con la aclaración." msgid "You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further." msgstr "Podrás seguir viéndola en la web al identificarte. Por favor responde a este correo si quieres comentar nuestra decisión." msgid "You're in. <a href=\"#\" id=\"send-request\">Continue sending your request</a>" msgstr "Bienvenido. <a href=\"#\" id=\"send-request\">Ahora puede continuar mandando su solicitud</a>" msgid "You're long overdue a response to your FOI request - " msgstr "La respuesta a tu solicitud de información está muy retrasada - " msgid "You're not following anything." msgstr "No estás recibiendo actualizaciones por correo." msgid "You've now cleared your profile photo" msgstr "Has borrado la foto de tu perfil" msgid "Your <strong>name will appear publicly</strong>\\n (<a href=\"{{why_url}}\">why?</a>)\\n on this website and in search engines. If you\\n are thinking of using a pseudonym, please\\n <a href=\"{{help_url}}\">read this first</a>." msgstr "" "<strong>Tu nombre aparecerá públicamente</strong> \n" " (<a href=\"{{why_url}}\">¿por qué?</a>)\n" " en esta web y en motores de búsqueda. Si estás\n" " pensando en utilizar un seudónimo, por favor \n" " <a href=\"{{help_url}}\">lee esto primero</a>." msgid "Your annotations" msgstr "Tus comentarios" msgid "Your batch request \"{{title}}\" has been sent" msgstr "" msgid "Your details, including your email address, have not been given to anyone." msgstr "Tus datos personales, incluyendo tu dirección de correo, no han sido compartido con nadie." msgid "Your e-mail:" msgstr "Tu correo:" msgid "Your email doesn't look like a valid address" msgstr "Su correo electrónico no parece una dirección válida" msgid "Your follow up has not been sent because this request has been stopped to prevent spam. Please <a href=\"{{url}}\">contact us</a> if you really want to send a follow up message." msgstr "Tu respuesta no ha sido enviada porque esta solicitud ha sido bloqueada para evitar spam. Por favor <a href=\"{{url}}\">contáctanos</a> si realmente quieres enviar una respuesta." msgid "Your follow up message has been sent on its way." msgstr "Tu mensaje está en camino." msgid "Your internal review request has been sent on its way." msgstr "Tu solicitud de revisión interna está en camino." msgid "Your message has been sent. Thank you for getting in touch! We'll get back to you soon." msgstr "Tu mensaje ha sido enviado. Gracias por escribir, nos pondremos en contacto contigo pronto." msgid "Your message to {{recipient_user_name}} has been sent" msgstr "Tu mensaje a {{recipient_user_name}} ha sido enviado" msgid "Your message to {{recipient_user_name}} has been sent!" msgstr "Tu mensaje a {{recipient_user_name}} ha sido enviado." msgid "Your message will appear in <strong>search engines</strong>" msgstr "Tu mensaje aparecerá en <strong>los motores de búsqueda</strong>" msgid "Your name and annotation will appear in <strong>search engines</strong>." msgstr "Tu nombre y su comentario aparecerán en los <strong>motores de búsqueda</strong>." msgid "Your name, request and any responses will appear in <strong>search engines</strong>\\n (<a href=\"{{url}}\">details</a>)." msgstr "" "Tu nombre, tu solicitud y cualquier respuesta aparecerán en los <strong>motores de búsqueda</strong>\n" " (<a href=\"{{url}}\">detalles</a>)." msgid "Your name:" msgstr "Tu nombre:" msgid "Your original message is attached." msgstr "Tu mensaje original está adjunto." msgid "Your password has been changed." msgstr "Tu contraseña ha sido cambiada." msgid "Your password:" msgstr "Tu contraseña:" msgid "Your photo will be shown in public <strong>on the Internet</strong>,\\n wherever you do something on {{site_name}}." msgstr "Tu foto será visible públicamente <strong>en Internet</strong>, cada vez que hagas algo en {{site_name}}." msgid "Your request '{{request}}' at {{url}} has been reviewed by moderators." msgstr "Tu solicitud '{{request}}' en {{url}} ha sido revisada por los moderadores." msgid "Your request on {{site_name}} hidden" msgstr "Tu solicitud en {{site_name}} oculta" msgid "Your request to add an authority has been sent. Thank you for getting in touch! We'll get back to you soon." msgstr "" msgid "Your request to add {{public_body_name}} to {{site_name}}" msgstr "" msgid "Your request to update the address for {{public_body_name}} has been sent. Thank you for getting in touch! We'll get back to you soon." msgstr "" msgid "Your request to update {{public_body_name}} on {{site_name}}" msgstr "" msgid "Your request was called {{info_request}}. Letting everyone know whether you got the information will help us keep tabs on" msgstr "Tu solicitud se llamaba {{info_request}}. Haznos saber si has recibido la información para ayudarnos a controlar a" msgid "Your request:" msgstr "Tu solicitud:" msgid "Your response to an FOI request was not delivered" msgstr "Tú respuesta a la solicitud de información no ha sido entregada" msgid "Your response will <strong>appear on the Internet</strong>, <a href=\"{{url}}\">read why</a> and answers to other questions." msgstr "Tu respuesta <strong>aparecerá en Internet</strong>, <a href=\"{{url}}\">lee por qué</a> y respuestas a otras preguntas." msgid "Your selected authorities" msgstr "Sus instituciones públicas seleccionadas" msgid "Your thoughts on what the {{site_name}} <strong>administrators</strong> should do about the request." msgstr "Opine sobre lo que los <strong>administradores</strong> de {{site_name}} deberían hacer con la solicitud." msgid "Your {{count}} Freedom of Information request" msgid_plural "Your {{count}} Freedom of Information requests" msgstr[0] "Tu {{count}} solicitud de información" msgstr[1] "Tus {{count}} solicitudes de información" msgid "Your {{count}} annotation" msgid_plural "Your {{count}} annotations" msgstr[0] "Tu {{count}} comentario" msgstr[1] "Tus {{count}} comentarios" msgid "Your {{count}} batch requests" msgid_plural "Your {{count}} batch requests" msgstr[0] "" msgstr[1] "" msgid "Your {{site_name}} email alert" msgstr "Tu alerta en {{site_name}}" msgid "Yours faithfully," msgstr "Un saludo," msgid "Yours sincerely," msgstr "Un saludo," msgid "Yours," msgstr "Un saludo," msgid "[Authority URL will be inserted here]" msgstr "" msgid "[FOI #{{request}} email]" msgstr "[Dirección de correo de la solicitud #{{request}}]" msgid "[{{public_body}} request email]" msgstr "[Dirección de correo del organismo {{public_body}}]" msgid "[{{site_name}} contact email]" msgstr "[Correo de contacto de {{site_name}}]" msgid "\\n\\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]" msgstr "\\n\\n[ {{site_name}} Nota: El texto anterior estaba mal codificado, y se han eliminado algunos carácteres extraños. ]" msgid "a one line summary of the information you are requesting, \\n\t\t\te.g." msgstr "" "un resumen de una línea de la información que solicitas, \n" "\t\t\tpor ejemplo" msgid "admin" msgstr "admin" msgid "alaveteli_foi:The software that runs {{site_name}}" msgstr "alaveteli_foi: El software en el que se basa {{site_name}}" msgid "all requests" msgstr "todas las solicitudes" msgid "all requests or comments" msgstr "todas las solicitudes o comentarios" msgid "all requests or comments matching text '{{query}}'" msgstr "" msgid "also called {{public_body_short_name}}" msgstr "también conocido como {{public_body_short_name}}" msgid "an anonymous user" msgstr "un usuario anónimo" msgid "and" msgstr "y" msgid "and update the status accordingly. Perhaps <strong>you</strong> might like to help out by doing that?" msgstr "y actualice su estado. ¿Tal vez <strong>tú</strong> quieres ayudarnos a hacerlo?" msgid "and update the status." msgstr "y actualice su estado." msgid "and we'll suggest <strong>what to do next</strong>" msgstr "y te sugeriremos <strong>qué hacer a continuación</strong>" msgid "anything matching text '{{query}}'" msgstr "" msgid "are long overdue." msgstr "están muy retrasados." msgid "at" msgstr "en" msgid "authorities" msgstr "organismos" msgid "beginning with ‘{{first_letter}}’" msgstr "comenzando con ‘{{first_letter}}’" msgid "but followupable" msgstr "pero suscribible" msgid "by" msgstr "antes de" msgid "by <strong>{{date}}</strong>" msgstr "antes de <strong>{{date}}</strong>" msgid "by {{user_link_absolute}}" msgstr "por {{user_link_absolute}}" msgid "comments" msgstr "comentarios" msgid "containing your postal address, and asking them to reply to this request.\\n Or you could phone them." msgstr "" "incluyendo tu dirección postal, y pidiéndoles que contesten a tu solicitud.\n" " O prueba a llamarles por teléfono." msgid "details" msgstr "detalles" msgid "display_status only works for incoming and outgoing messages right now" msgstr "display_status sólo funciona para mensajes de entrada y salida ahora mismo" msgid "during term time" msgstr "durante el periodo escolar" msgid "edit text about you" msgstr "edita el texto sobre ti" msgid "even during holidays" msgstr "incluso durante las vacaciones" msgid "everything" msgstr "todo" msgid "external" msgstr "externa" msgid "has reported an" msgstr "ha denunciado un" msgid "have delayed." msgstr "han retrasado." msgid "hide quoted sections" msgstr "ocultar partes citadas" msgid "in term time" msgstr "durante el periodo escolar" msgid "in the category ‘{{category_name}}’" msgstr "en la categoría ‘{{category_name}}’" msgid "internal error" msgstr "error interno" msgid "internal reviews" msgstr "revisiones internas" msgid "is <strong>waiting for your clarification</strong>." msgstr "está <strong>esperando su aclaración</strong>." msgid "just to see how it works" msgstr "sólo para ver cómo funciona" msgid "left an annotation" msgstr "dejó un comentario" msgid "made." msgstr "hecho." msgid "matching the tag ‘{{tag_name}}’" msgstr "con la etiqueta ‘{{tag_name}}’" msgid "messages from authorities" msgstr "mensajes de organismos" msgid "messages from users" msgstr "mensajes de usuarios" msgid "move..." msgstr "mover..." msgid "new requests" msgstr "solicitudes nuevas " msgid "no later than" msgstr "no más tarde de" msgid "no longer exists. If you are trying to make\\n From the request page, try replying to a particular message, rather than sending\\n a general followup. If you need to make a general followup, and know\\n an email which will go to the right place, please <a href=\"{{url}}\">send it to us</a>." msgstr "" "ya no existe. \n" "Desde la página de la solicitud, intenta responder a un mensaje en concreto, en vez de\n" " responder a la solicitud en general. Si necesitas hacerlo y tienes una dirección de\n" " correo válida, por favor <a href=\"{{url}}\">mándanosla</a>." msgid "normally" msgstr "normalmente" msgid "not requestable due to: {{reason}}" msgstr "no puede recibir solicitudes por: {{reason}}" msgid "please sign in as " msgstr "por favor abra una sesión como " msgid "requesting an internal review" msgstr "pidiendo una revisión interna" msgid "requests" msgstr "solicitudes" msgid "requests which are successful" msgstr "" msgid "requests which are successful matching text '{{query}}'" msgstr "" msgid "response as needing administrator attention. Take a look, and reply to this\\nemail to let them know what you are going to do about it." msgstr "" "respuesta necesita intervención del administrador. Revísela, y conteste a este\n" "correo para indicarles qué va a hacer al respecto." msgid "send a follow up message" msgstr "envíe un mensaje de seguimiento" msgid "set to <strong>blank</strong> (empty string) if can't find an address; these emails are <strong>public</strong> as anyone can view with a CAPTCHA" msgstr "<strong>déjalo en blanco</strong> si no puedes encontrar una dirección válida; estas direcciones <strong>son públicas</strong>, cualquiera puede verlas rellenando un CAPTCHA" msgid "show quoted sections" msgstr "mostrar partes citadas" msgid "sign in" msgstr "abrir sesión" msgid "simple_date_format" msgstr "simple_date_format" msgid "successful requests" msgstr "solicitudes exitosas" msgid "that you made to" msgstr "que hiciste a" msgid "the main FOI contact address for {{public_body}}" msgstr "la dirección de contacto de {{public_body}}" #. This phrase completes the following sentences: #. Request an internal review from... #. Send a public follow up message to... #. Send a public reply to... #. Don't want to address your message to... ? msgid "the main FOI contact at {{public_body}}" msgstr "el contacto en {{public_body}}" msgid "the requester" msgstr "el solicitante" msgid "the {{site_name}} team" msgstr "el equipo de {{site_name}}" msgid "to read" msgstr "lea" msgid "to send a follow up message." msgstr "mandar un mensaje de seguimiento." msgid "to {{public_body}}" msgstr "a {{public_body}}" msgid "unknown reason " msgstr "motivo desconocido " msgid "unknown status " msgstr "estado desconocido " msgid "unresolved requests" msgstr "solicitudes no resueltas" msgid "unsubscribe" msgstr "cancelar suscripción" msgid "unsubscribe all" msgstr "cancelar todas las suscripciones" msgid "unsuccessful requests" msgstr "solicitudes fallidas" msgid "useful information." msgstr "información útil." msgid "users" msgstr "usuarios" msgid "what's that?" msgstr "¿Qué es eso?" msgid "{{count}} FOI requests found" msgstr "{{count}} solicitudes de información encontradas" msgid "{{count}} Freedom of Information request to {{public_body_name}}" msgid_plural "{{count}} Freedom of Information requests to {{public_body_name}}" msgstr[0] "{{count}} solicitud de información a {{public_body_name}}" msgstr[1] "{{count}} solicitudes de información a {{public_body_name}}" msgid "{{count}} person is following this authority" msgid_plural "{{count}} people are following this authority" msgstr[0] "{{count}} persona esta siguiendo este organismo" msgstr[1] "{{count}} personas estan siguiendo este organismo" msgid "{{count}} request" msgid_plural "{{count}} requests" msgstr[0] "{{count}} solicitud" msgstr[1] "{{count}} solicitudes" msgid "{{count}} request made." msgid_plural "{{count}} requests made." msgstr[0] "{{count}} solicitud enviada." msgstr[1] "{{count}} solicitudes enviadas." msgid "{{existing_request_user}} already\\n created the same request on {{date}}. You can either view the <a href=\"{{existing_request}}\">existing request</a>,\\n or edit the details below to make a new but similar request." msgstr "" "{{existing_request_user}} ya\n" " envió la misma solicitud el {{date}}. Puedes ver <a href=\"{{existing_request}}\">la solicitud existente</a>,\n" " o editar la tuya a continuación para enviar una nueva similar a la anterior." msgid "{{foi_law}} requests to '{{public_body_name}}'" msgstr "{{foi_law}} le solicita a '{{public_body_name}}'" msgid "{{info_request_user_name}} only:" msgstr "Sólo {{info_request_user_name}}:" msgid "{{law_used_full}} request - {{title}}" msgstr "solicitud {{law_used_full}} - {{title}}" msgid "{{law_used}} requests at {{public_body}}" msgstr "Solicitudes de información a {{public_body}}" msgid "{{length_of_time}} ago" msgstr "hace {{length_of_time}}" msgid "{{number_of_comments}} comments" msgstr "{{number_of_comments}} comentarios" msgid "{{public_body_link}} answered a request about" msgstr "{{public_body_link}} respondió a una solicitud sobre" msgid "{{public_body_link}} was sent a request about" msgstr "{{public_body_link}} recibió una solicitud sobre" msgid "{{public_body_name}} only:" msgstr "Sólo {{public_body_name}}:" msgid "{{public_body}} has asked you to explain part of your {{law_used}} request." msgstr "{{public_body}} ha pedido que explicas parte de tu pedido de {{law_used}}." msgid "{{public_body}} sent a response to {{user_name}}" msgstr "{{public_body}} respondió a {{user_name}}" msgid "{{reason}}, please sign in or make a new account." msgstr "{{reason}}, por favor abre una sesión, o crea una nueva cuenta." msgid "{{search_results}} matching '{{query}}'" msgstr "{{search_results}} encontrados por '{{query}}'" msgid "{{site_name}} blog and tweets" msgstr "{{site_name}} blog y tweets" msgid "{{site_name}} covers requests to {{number_of_authorities}} authorities, including:" msgstr "{{site_name}} incluye solicitudes a {{number_of_authorities}} organismos públicos, incluyendo:" msgid "{{site_name}} sends new requests to <strong>{{request_email}}</strong> for this authority." msgstr "{{site_name}} envía nuevas solicitudes a <strong>{{request_email}}</strong> para este organismo." msgid "{{site_name}} users have made {{number_of_requests}} requests, including:" msgstr "Los usuarios de {{site_name}} han hecho {{number_of_requests}} solicitudes, incluyendo:" msgid "{{thing_changed}} was changed from <code>{{from_value}}</code> to <code>{{to_value}}</code>" msgstr "{{thing_changed}} ha pasado de <code>{{from_value}}</code> a <code>{{to_value}}</code>" msgid "{{title}} - a Freedom of Information request to {{public_body}}" msgstr "{{title}} - una solicitud de información a {{public_body}}" msgid "{{title}} - a batch request" msgstr "" msgid "{{user_name}} (Account suspended)" msgstr "{{user_name}} (Expulsado)" msgid "{{user_name}} - Freedom of Information requests" msgstr "{{user_name}} - Peticiones de acceso a la información" msgid "{{user_name}} - user profile" msgstr "{{user_name}} - perfil de usuario" msgid "{{user_name}} added an annotation" msgstr "{{user_name}} añadió un comentario" msgid "{{user_name}} has annotated your {{law_used_short}} \\nrequest. Follow this link to see what they wrote." msgstr "" "{{user_name}} ha comentado tu solicitud {{law_used_short}}. \n" "Sigue este enlace para ver lo que ha escrito." msgid "{{user_name}} has used {{site_name}} to send you the message below." msgstr "{{user_name}} ha usado {{site_name}} para enviarle el siguiente mensaje." msgid "{{user_name}} sent a follow up message to {{public_body}}" msgstr "{{user_name}} envió un mensaje a {{public_body}}" msgid "{{user_name}} sent a request to {{public_body}}" msgstr "{{user_name}} envió una solicitud a {{public_body}}" msgid "{{user_name}} would like a new authority added to {{site_name}}" msgstr "{{user_name}} le gustaría que se agregue una nueva institución pública a {{site_name}}" msgid "{{user_name}} would like the email address for {{public_body_name}} to be updated" msgstr "{{user_name}} le gustaría que la dirección de correo electrónico de {{public_body_name}} sea actualizada" msgid "{{username}} left an annotation:" msgstr "{{username}} dejó un comentario:" msgid "{{user}} ({{user_admin_link}}) made this {{law_used_full}} request (<a href=\"{{request_admin_url}}\">admin</a>) to {{public_body_link}} (<a href=\"{{public_body_admin_url}}\">admin</a>)" msgstr "{{user}} ({{user_admin_link}}) hizo esta solicitud {{law_used_full}} (<a href=\"{{request_admin_url}}\">admin</a>) a {{public_body_link}} (<a href=\"{{public_body_admin_url}}\">admin</a>)" msgid "{{user}} made this {{law_used_full}} request" msgstr "{{user}} hizo esta solicitud de {{law_used_full}}"