Doctoral theses at NTNU, 2023:451
Ole Kristian Aamot
Location for World Wide Web
Location Search on World Wide Web 
Doctor
ISBN 978-82-326-7606-4 (printed ver.)
ISBN 978-82-326-7605-7 (electronic ver.)
ISSN 1503-8181 (printed ver.)
ISSN 2703-8084 (online ver.)
Doctoral theses at NTNU, 2023:451
NTNU
Technology
Engineering
Philosophiae Doctor
Thesis for the Degree
Technology and Electrical Engineering
2023:451
Department of Computer Science
Norwegian University of Science and Technology
Faculty of Information Technology


Ole Kristian Aamot
Location for World Wide Web
Location Search on World Wide Web 
Thesis for the Degree of Philosophiae Doctor
Trondheim, December 2023
Norwegian University of Science and Technology
Faculty of Information Technology and Electrical Engineering 
Department of Computer Science

NTNU
Norwegian University of Science and Technology
Thesis for the Degree of Philosophiae Doctor
Faculty of Information Technology and Electrical Engineering 
Department of Computer Science
© Ole Kristian Aamot
ISBN 978-82-326-7606-4 (printed ver.)
ISBN 978-82-326-7605-7 (electronic ver.)
ISSN 1503-8181 (printed ver.)
ISSN 2703-8084 (online ver.)
Doctoral theses at NTNU, 2023:451
Printed by NTNU Grafisk senter

Piperpal Geolocation Search Engine

Piperpal (https://www.piperpal.com/) is a geolocation search engine where you can tag geolocation with a location on World Wide Web and your current geopoint with a mobile device such as the Google Pixel 7 smartphones with Android 13 using the Piperpal application https://play.google.com/store/apps/details?id=com.piperpal.api.android with full source code available under the MIT License on https://www.github.com/piperpal/

Location-based Queries

The discussion of Location-based Queries began in 2005 at the International Conference on Web-Age Information Management (Searching the World Wide Web for Local Services and Facilities: A Review on the Patterns of Location-Based Queries, Asadi, 2005) with the newly introduction of GPS (Global Position Satellite) mobile support and new smartphones such as Apple iPhone, Blackberry and Google Android-based smart mobile devices with GPS support in 2008.

Location-aware Content Tag: <location>,&location markup

I am introducing the new <location> tag and &<location> syntax for document markup of location-based content in HTML by creating the Data Type Definition published on http://github.com/location

The new tag will make it easier for content providers to state that the HTML content they are publishing is geographically positioned and meant for indexing and displaying on services like Google Maps / Google Now. The motivation behind this work is new location-based content retrieval, and would open a range of new ways to advertise geographically within a given radius and time interval.

Example: &concert

HTML Document with <location> tag with &concert example Daryl Hall & John Oates playing a concert at the Greek Theater at UC Berkeley. The location tag is &concert.

Piperpal: Location-aware markup

My idea is that the content on a website is marked up according to a location tag and that this tag decides which content that is meant to be indexed and eligble for placing a ad on. The content producers would tag their content with a location tag, the advertisements mark up their catalog with location-aware radius ads, and the users can embed the ads in their posts with a new location tag syntax such as &concert that could be implemented by Google services such as Gmail and Google+.

Pseudo code for logic of search for nearby matches

if (notBefore < NOW() < notAfter || ((&UserLoc -
radius) < (geo) < (&UserLoc + radius)) → display

Piperpal is the first site that I am implementing for making a resource for location-based tags.

On http://piperpal.com/ I added the form that lets the users insert the Name, Location, and Service parameter and pay by credit card (via Stripe) to add the entry. The mapping between the content produced by a content provider, the ad by the advertiser and the tagging by individual user is done on www.piperpal.com/<location> where the location tag example for <location> would be &concert and the URI would be www.piperpal.com/concert

MariaDB Database Structure

A MariaDB (http://www.mariadb.org/) database structure for our implementation of "Location Search on World Wide Web” is given as SQL instructions here:

CREATE TABLE piperpal (
       id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
       name VARCHAR(100) NOT NULL DEFAULT '',
       service VARCHAR(1024) NOT NULL,
       location VARCHAR(1024) NOT NULL,
       modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       created TIMESTAMP NULL DEFAULT NULL,
       glat DECIMAL(10, 8) NOT NULL,
       glon DECIMAL(11, 8) NOT NULL, 
       paid MEDIUMINT(16) UNSIGNED NOT NULL,
       token VARCHAR(32) NOT NULL,
       type VARCHAR(32) NOT NULL,
       email VARCHAR(256) NOT NULL,
       PRIMARY KEY (id)
);

The Apache API mapping of "http://piperpal.com/concert"

RewriteEngine On
RewriteRule ^([\sa-åA-Å0-9]+)$ /api/ [L]

Piperpal API and jQuery representation of http://piperpal.com/concert

The API will query the user's link location and geoposition through the AJAX script and present a user with content in the nearest geographical approximity according to the Haversine formula.

Piperpal provides a jQuery function with a variable with a the list of all location entries for a given location tag nearby a geographical position for the device. This jQuery function can then be used by third-party developers who want to show all entries for a given location-based tag entry accepted on piperpal.com

Computing shortest Haversine distance

The distance along the surface of the (spherical) Earth between two arbitrary points, in degrees is determined by the Spherical Cosine Law, also known as the Haversine Formula. We use this law to compute the nearest entries on piperpal.com measured from the user's geolocation.

The jQuery function on "http://piperpal.com/concert"

The jQuery function on "http://piperpal.com/concert"

$(function() 
{ var locations = '{
  "locations" : [' + '
  {"id": "11884992",
  "name": "Løren",
  "service": "Food",
  "location": "https://www.loren.no/",
  "modified": "2023-07-04 12:00:00",
  "created": "2023-07-05 12:00:00",
  "glat": "59.92929197",
  "glon": "10.79022856",
  "paid": "0", 
  "token": "tok_1NPyQRAgJ7jHvJPRPHRLaktB",
  "type": "card", 
  "distance": "44.61835617894167",
  "email": "ole@aamot.software"},
  {"id": "11884996",
  "name": "@HappyJuly4th",
  "service": "Food",
  "location": "https://www.piperpal.com/Food/@HappyJuly4th",
  "modified": "2023-07-18 12:00:00",
  "created": "2023-07-25 12:00:00",
  "glat": "59.92929074",
  "glon": "10.79037934",
  "paid": "1",
  "token": "tok_1NQ1oDAgJ7jHvJPRGaiDmiKR",
  "type": "card",
  "distance": "44.62663072803127",
  "email": "ole@aamotsoftware.no"}]}';

Future Piperpal work

Convolutional Neural Net to group the nearby points. Plan to do lookups with a Convolution Neural Network [CNN] using a matrix with all of the entries within a radius away from the user's location for a given time as computed by a convolution matrix for the longitude and latitude.

Provide control panel that costs $25 per year/usage.

Wizard to define service or offer.

Service Category

Example: Shoes or clothing. Sports clothing/shoes. Describe your service/offer: Shoes

Example: Welcome to Oslo's largest flip flop offers.

Upload/Connect image, url, video, audio.

Decide amount of clicks and enter the email address for accessing statistics.

Payment: Stripe / Paypal / Google Wallet / Android Pay

Statistics

Perl Module - Piperpal.pm

The software programming module for our implementation of "Location Search on World Wide Web" is given as dynamically loadable Perl5 (version 5.24.1) Module here:

package Piperpal;

# Copyright (C) 2015 Ole Aamot
#
# Author: oka@oka.no
#
# Date: 2015-08-22T16:45:00+01
#
# Field: Incremental, prime number, sql, perl
#
# URL: https://www.piperpal.com/Piperpal.pm

#######################
# LOAD MODULES
#######################
use strict;

use lib '/home/4/p/piperpal/share/perl/5.10.1/';
use warnings FATAL => 'all';

use 5.008001;
use Encode qw();

use HTTP::Request::Common;
use DBI;
use CGI;
# use LWP;
use WWW::Mechanize;
use JSON -support_by_pp;
use HTML::Entities;
use Math::Round;
use DateTime;

my @Piperpal;

BEGIN {
    @Piperpal = qw{input_location input_publisher lns_item lns_market_item is_valid is_paid initialize update_location select_location} 
}

sub get_locations {
    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
    $dbh->do ("SELECT DISTINCT name,glat,glon FROM yaylocation WHERE paid > '0' ORDER by name;");
    my $sth = $dbh->prepare ("SELECT DISTINCT name,glat,glon FROM yaylocation ORDER by name;");
    $sth->execute();
    while (my $ref = $sth->fetchrow_hashref()) {
     if ('GET' eq $c->request_method && $c->param('locationservicename') && $c->param('location')) {
         if ($ref->{'name'} == $c->param('locationservicename')) {
             print "<option selected value=" . $ref->('glat') . "," . $ref->{'glon'} . ">" . $ref->{'name'} . "</option>";
         } else {
             print "<option value=" . $ref->('glat') . "," . $ref->{'glon'} . ">" . $ref->{'name'} . "</option>";
             
         } 
     }
    }
    $sth->finish();
    $dbh->disconnect();    
    return;
}

sub get_services {
    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
    $dbh->do ("SELECT DISTINCT service,name,glat,glon FROM piperpal ORDER by service;");
    my $sth = $dbh->prepare ("SELECT DISTINCT service,name,glat,glon FROM piperpal WHERE ORDER by service;");
    $sth->execute();
    if ('GET' eq $c->request_method && $c->param('service')) {
     while (my $ref = $sth->fetchrow_hashref()) {
         if ($ref->{'service'} == $c->param('service')) {
             print "<option selected value=" . $ref->('glat') . "," . $ref->{'glon'} . ">" . $ref->{'service'} . "</option>";
         } else {
             print "<option value=" . $ref->('glat') . "," . $ref->{'glon'} . ">" . $ref->{'service'} . "</option>";
             
         } 
     }
    }
    $sth->finish();
    $dbh->disconnect();    
    return;
}
sub input_searchers {
    my @radiuses = (1,2,5,10,25,50,100,250,500,
                 750,1000,1250,1500,2000,2500,
                 3000,4000,5000, 6000,7000,8000,9000,10000,
                 20000,
                 40075);
    my $r;
    my $sth;
    my $dbh;
    my $c = CGI->new;
    my $servicep;
    print "<form onsubmit='updateGeo()' method='GET' action='https://www.piperpal.com/#results' id='formID'>";
    print '<table>';
    if ('GET' eq $c->request_method && $c->param('query')) {
     print '<tr><td><center><input size="30" type="text" autofocus class="input_form_custom" id="query" name="query" placeholder="Piperpal-search" value="' . HTML::Entities::encode($c->param('query')) . '" autocomplete="query webauthn" /></center></td></tr>';
     #      $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});                
     #      $dbh->{'mysql_enable_utf8'} = 1;                                           
     #      if ($c->param('query')) {                                                   
     #          $sth = $dbh->prepare ("SELECT name,location,service FROM piperpal WHERE (name LIKE '%" . $c->param('query') . "%' OR service LIKE '%" . $c->param('query') . "%') ORDER by modified DESC;");                                  $sth->execute();                                                        
   #          while (my $ref = $sth->fetchrow_hashref()) {
   #             print '<tr><td></td><td>';
   #             lns_item($ref->{'name'}, $ref->{'location'}, $ref->{'service'}, $ref->{'glat'}, $ref->{'glon'}, $ref->{'modified'}, $ref->{'created'}, $ref->{'distance_in_km'});
   #              print '</td></tr>';
# #   }
   #       }
   #:        $sth->finish();
   # $ref->{'name'}, $ref->{'location'}, $ref->{'service'}, $ref->{'glat'}, $ref->{'glon'}, $ref->{'modified'}, $ref->{'created'}, $ref->{'distance_in_km'}
    } else {
   print '<tr><td><center><input size="30" type="text" class="input_form_custom" id="query" name="query" placeholder="Where to think&quest;" /></center></td>';
   print '<td><select size="8" type=hidden name="radius" id="radius" value="1000" class="input_form_custom">';
   foreach $r (@radiuses) {
       if ($c->param('radius')) {
           if ($c->param('radius')==$r) {
           print "<option value='" . $r . "' selected>In " . $r . " km radius</option>";
       } else {
           print "<option value='" . $r . "'>In " . $r . " km radius</option>";
       }
       } else {
       if ($r == 5) {
           print "<option value='" . $r . "' selected>In " . $r . " km radius</optio>";      
       } else {
           print "<option value='" . $r . "'>In " . $r . " km radius</option>";
       }
       }
       
   }
   print '</select></td>';
    }
    print '<td>&nbsp;</td><td><input type="submit" id="search" name="search" value="Go" /></td></tr></table>';
    print "<span id='status'><input type='hidden' name='glat' /><input type='hidden' name='glon' /></span>\n";
    print "</form>";
    print "<h3>Be discovered by the world around you</h3>";
    print "<p><a href='https://www.piperpal.com/google.html'>Submit entries in Piperpal\'s Location-aware Search Engine</a></p>";
    #&Piperpal::input_publisher();
    #&Piperpal::insert_publisher();
    print '<p>Location JavaScript API: <a href="http://api.piperpal.com/location/">Piperpal</p>';;
    print '<p>Mobile Browsers: <a href="http://www.chromium.org/">Chromium</a>, <a href="http://www.mozilla.org/firefox">Firefox</a>, <a href="http://www.vivaldi.com/">Vivaldi</a></p>';;
    print '<p><a href="https://www.piperpal.com/?query=&radius=5&search=Go&service=Books&glat=55.6828273&glon=12.6082921#results">Copenhagen</a>, <a href="https://www.piperpal.com/?query=&radius=5&search=Go&service=Books&glat=37.419559&glon=-122.0897767#results">Google Visitor Center</a>, <a href="https://www.piperpal.com/?query=&radius=5&search=Go&service=Books&glat=51.5073219&glon=-0.1276474#results">London</a>, <a href="https://www.piperpal.com/?query=&radius=5&search=Go&service=Books&glat=40.6399278&glon=-73.7786925#results">New York</a>, <a href="https://www.piperpal.com/?query=&radius=5&search=Go&service=Books&glat=48.8566969&glon=2.3514616#results">Paris</a></p>';
    print '<p>LLM: <a href="http://chat.openai.com/">ChatGPT</a>, <a href="https://ai.meta.com/llama/">Llama 2</a>, <a href="https://bard.google.com/">Bard</a>, <a href="http://ai.bing.com/">Bing</a></p>';    
    print '<p>Maps: <a href="http://maps.google.com/">Google Maps</a>, <a href="http://www.openstreetmap.org/">Open Street Map</a>, <a href="http://www.bing.com/maps/">Bing Maps</a>, <a href="http://maps.apple.com/">Apple Maps</a></p>';
    print '<p>Search: <a href="http://www.google.com/">Google</a>, <a href="http://www.duckduckgo.com/">DuckDuckGo</a>, <a href="http://www.bing.com/">Bing</a>, <a href="http://www.yahoo.com/">Yahoo!</a></p>';
}

sub input_publisher {

    my $c = CGI->new;
    print "<tr><td width='60'>&nbsp;</td><td><form onsubmit='updateGeo()' id='welcomeForm' name='welcomeForm' action='https://api.piperpal.com/location/push.php' method='POST'>";
    print '<span class="input_form">';
    print '<img src="img/Name_Icon.png" title="Name of Location-aware Content Tag" class="icon_form" height="70" width="70">';
    if ($c->param('query')) {
   print '<input type="text" id="name" class="input_form_custom" name="name" placeholder="Name" value=' . HTML::Entities::encode($c->param('query')) . ' />';
    } else {
   print '<input type="text" id="name" class="input_form_custom" name="name" placeholder="Name" />';
    }
    print '</span>';
    print '</td></tr><tr><td width=60>&nbsp;</td><td>';
    print '<span class="input_form">';
    print '<img src="img/Location_Icon.png" title="URL of Location-aware Content Tag" class="icon_form" height="70" width="70">';
    print '<input type="text" id="location" class="input_form_custom" name="location" placeholder="http://">';
    print '</span>';
    print '</td></tr><tr><td width=60>&nbsp;</td><td>';
   print '<span class="input_form">';
    print '<img src="img/Service_Icon.png" title="Service type of Location-aware Content Tag" class="icon_form" height="70" width="70">';
    print '</td></tr><tr><td width=60>';
    print '<select id="simple-search-location" class="input-large js-search-location" id="service" name="service" class=biginput><option value="Restaurant">Restaurant</option><option value="Bar">Bar</option><option value="Concert">Concert</option><option value="Film">Film</option><option value="Books">Books</option><option value="Health">Health</option><option value="Clothes">Clothes</option><option value="Food">Food</option><option value="Music">Music</option><option value="Electronics">Electronics</option><option value="Transport">Transport</option><option value="Rental">Rental</option><option value="Search">Search</option></select></td></tr>';
    print '<input type="text" id="service" name="service" placeholder="Service">';
    # print '<h3>News</h3>';
    #print '<p><b>2021</b></p>';    
    #print '<p><i><a href="http://www.aamotsoftware.com/">Aamot Software</a>\'s second functional example of HTML with location tagging and fetching was stored on <a href="http://piperpal.com/cft/s/">http://piperpal.com/cft/s/</a></i></p>';
    #print '<p><b>2020</b></p>';
    #print '<p><i><a href="http://www.aamotsoftware.com/">Aamot Software</a>\'s Indexer for Piperpal written in the programming language Python can now recursively index location tags as specified on <a href="http://www.aamotsoftware.com/location.html">http://www.aamotsoftware.com/location.html</a> from web pages that are listed for such indexing on <a href="http://www.aamotsoftware.com/location-source.html">http://www.aamotsoftware.com/location-source.html</a></i></p>';
    #print '<p><b>2015</b></p>';    
    #print '<p><i><a href="http://www.aamotsoftware.com/">Aamot Software</a>\'s first practical example of location tagging with Piperpal was stored on <a href="http://piperpal.com/Google">http://piperpal.com/Google</a> at a lunch table with <a href="http://www.norvig.com/">Peter Norvig</a> in the Google Visitor Center in Mountain View, California in 2015 where he mentioned crowd sourcing of location tags with a neural network filter as future work.</i></p>';
    #print '<p><i><a href="http://www.aamotsoftware.com/">Aamot Software</a>\'s presentation for <a href="http://research.google.com/">Google Research</a>: <a href="http://www.piperpal.com/doc/3.0/Piperpal-Location-aware-ContentTag.pdf">Location-aware Content Tag: &lt;location&gt;,&location markup</a></p>';

    print '<span class="row row-condensed space-top-2 space-2">
  <span class="col-sm-6">
        <label for="simple-search-tourin" class="screen-reader-only">
  Tour in
        </label>
        <input
  id="simple-search-tourin"
          type="text"
          name="notBefore"
          class="input-large tourin js-search-tourin"
          placeholder="Not Before">
      </span>
      <span class="col-sm-6">
        <label for="simple-search-tourout" class="screen-reader-only">
          Tour out
          </label>
        <input
          id="simple-search-tourout"
          type="text"
          name="notAfter"
          class="input-large tourout js-search-tourout"
          placeholder="Not After">
      </span>
    </span>';
  #  print '</span>';
    print "<span id='status_publisher'>\n";
#    print "<span class='input_form_custom'>";
    print "<input id='glat' class='input_form_custom' type='text' name='glat' placeholder='Latitude' size=35 />\n";
#    print "<span class='input_form_custom'>
    print "<input id='glon' class='input_form_custom' type='text' name='glon' placeholder='Longitude' size=35 />\n";
    print "</span>\n";
    print "<input type='hidden' name='c' value='INSERT' />\n";
    print '<span class="send_form">';
    print "<script src='http://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_9UbKhDJJWaAFnMjYQTBA8I9i00H8Z5eMmL' data-amount='0' data-name='Aamot Software' data-description='Piperpal Entry ($0.01 USD)' data-image='/img/Location_Icon.png'></script>";
    # print '<input class="custom_send_button" type="submit" value="PAY WITH CARD">';
    print '</span>';
    print '</form>';
    print '</td></tr>';
    
#    print "<input type='hidden' name='c' value='INSERT' />\n";
#    print "<table cellpadding=5><tr>";
    #   print "<td><a href='http://www.piperpal.com/Piperpal'><img border=0 width=16 height=16 src='js-icon.png' /></td>";
  #  print "<td><input size=16 type=text name=name class=biginput id=name placeholder='Name' /></td>\n";
    # print "<td><input size=20 type=text name=location class=biginput id=location placeholder='http://' /></td>\n";
    #print "<td><input size=16 type=text name=service class=biginput id=service placeholder='Service' /></td>\n";
    #print "<span id='status'><input type='hidden' name='glat' placeholder='Latitude' size=16 /><input type='hidden' name='glon' placeholder='Longitude' size=16 /></span>\n";
    # print "<td><form action='http://www.piperpal.com/checkout.php' method='POST'><script src='https://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_odDlc1NMTUJdPN4WC2VTLvvu' data-amount='0' data-name='Aamot Software' data-description='1 Hour Programming/Support (10 cent)' data-image='/128x128.png'></script></td>";
  #  print "</tr>\n";
   # print "</form>\n";


}

sub input_advertiser {

    my $c = CGI->new;
    print "<input type='hidden' name='c' value='INSERT' />\n";
    print "<table cellpadding=5><tr>";
    print "<td>Word</td><td><input type=text name=name class=biginput id=name placeholder='Name'></textarea></td>\n";
    print "<td><input size=20 type=text name=location class=biginput id=location placeholder='http://' /></td>\n";
    print "<td><input size=16 type=text name=service class=biginput id=service placeholder='Service' /></td>\n";
#    print '<td><span class="row row-condensed space-top-2 space-2">
#      <span class="col-sm-6">
#        <label for="simple-search-tourin" class="screen-reader-only">
#          Tour in
#        </label>
#        <input
#          id="simple-search-tourin"
#          type="text"
#          name="notBefore"
#          class="input-large tourin js-search-tourin"
#          placeholder="Not Before">
#      </span>
#      <span class="col-sm-6">
#        <label for="simple-search-tourout" class="screen-reader-only">
#          Tour out
#          </label>
#       <input
#          id="simple-search-tourout"
#          type="text"
#          name="notAfter"
#          class="input-large tourout js-search-tourout"
#          placeholder="Not After">
#      </span>
#    </span>';
    print "<span id='status'><input type='hidden' name='glat' placeholder='Latitude' size=16 /><input type='hidden' name='glon' placeholder='Longitude' size=16 /></span>\n";
    print "<td><form action='https://api.piperpal.com/location/push.php' method='POST'><script src='http://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_test_EeI0KTkAXtAyW1ajpKukLZPm00ChuDtuP8' data-amount='4500' data-name='Aamot Software' data-description='1 Hour Programming/Support (45 USD)' data-image='/img/Location_Icon.png'></script></td>";
    print "</tr>\n";
    print "</form>\n";

}

sub lns_item {
    my $c = CGI->new;
    # my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});

    my $name = shift(@_);
    my $location = shift(@_);
    my $service = shift(@_);
    my $glat = shift(@_);
    my $glon = shift(@_);
    my $modified = shift(@_);
    my $created = shift(@_);
    my $distance = shift(@_);

    print "<tr><td width=60>&nbsp;</td><td>";
    print "<form onsubmit='updateGeo()' id='lnsForm' name='lnsForm' action='https://api.piperpal.com/location/push.php' method='POST'>";
    # print '<span class="name_form input_form">';
    print "<location name='" . $name . "' href='" . $location . "' service='" . $service . "' address='" . $location . "' lat='" . $glat . "' lon='" . $glon . "'><a href='" . $location . "'><h2>" . $name . "</h2></a></location>";    
#    print "<h3>" . nearest(0.1, $distance) . " km away</h3>";
#    print "<script type='text/javascript' lang='JavaScript'>";
#    print "var latpoint = document.getElementById('glat');";
#    print "var longpoint = document.getElementById('glon');";  
#    print "latpoint.value = position.coords.latitude;";
#    print "longpoint.value = position.coords.longitude;";
#    print "print latpoint.value;";
#    print "print longpoint.value;";
#    print "</script>";
#    print "111.045*DEGREES(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat))))";
    print "<table valign='left'>";
    print "<tr><td width='60'>";
    print '<a href="/' . $name . '"><img src="/img/Name_Icon.png" title="Name of Location-aware Content Tag" height="70" width="70"></a>';
    print '</td><td><input type="text" id="' . $name .'" name="name" placeholder="Name" value="' . $name . '"></td></tr>';
  #  print '</span>';
#    print '<br>';
    #    print '<span class="website_form input_form">';
    print "<tr><td width='60'>";    
    print '<a href="' . $location . '"><img src="/img/Location_Icon.png" title="URL of Location-aware Content Tag" height="70" width="70"></a>';
    print '</td><td><input type="text" id="' . $name . '_location' . '" name="location" placeholder="http://" value="' . $location . '">';
 #   print '</span>';
 #    print '<br>';
    #    print '<span class="service_form input_form">';
    print "</td></tr><tr><td width='60'>";        
    print '<a href="/service/' . $service . '"><img src="/img/Service_Icon.png" title="Service type of Location-aware Content Tag" height="70" width="70"></a></td><td>';
    print '<input type="text" id="' . $name . '_service' . '" name="service" placeholder="Service" value="' . $service . '">';
    print "</td></tr><tr><td width='60'>";            
#    print '<span class="row row-condensed space-top-2 space-2">
#      <span class="col-sm-6">
#        <label for="simple-search-tourin" class="screen-reader-only">
#          Tour in
#        </label>
#        <input
#          id="datepicker"
#          type="text"
#          name="notBefore"
#          class="input-large tourin js-search-tourin"
#          placeholder="Not Before" value="' . $created . '">
#      </span>
#      <span class="col-sm-6">
#        <label for="simple-search-tourout" class="screen-reader-only">
#          Tour out
#          </label>
#        <input
#          id="datepicker"
#          type="text"
#          name="notAfter"
#          class="input-large tourout js-search-tourout"
#          placeholder="Not After" value="' . $modified . '">
#      </span>
#    </span>';
#    print '</span>';
    print "</td></tr><tr><td width='60'>";            
    print "<span id='status_lns'>\n";
#    print "<span class='service_form input_form'>";
    print "<img src='/img/Latitude_Icon.png' alt='Icon2' height='70' width='70'></td><td><input id='" . $name . "_glat' type='text' name='glat' placeholder='Latitude' size=35 value='" . $glat . "' />\n";
    print "</td></tr><tr><td width='60'>";

#</span>\n";

#    print "<span class='input_form_custom'><img src='img/Latitude_Icon.png' alt='Icon2' class='icon_form' height='70' width='70'><input id='" . $name . "_glat' class='input_form_custom' type='text' name='glat' placeholder='Latitude' size=32 value='" . $glat . "' /></span>\n";

    #   print "<span class='service_form input_form'>
    print "</td></tr><tr><td width='60'>";    
    print "<img src='/img/Longitude_Icon.png' alt='Icon2' height='70' width='70'></td><td><input id='" . $name . "_glon' type='text' name='glon' placeholder='Longitude' size=35 value='" . $glon . "' />\n";
#</span>\n";

 #   print "<span class='input_form_custom'><img src='img/Longitude_Icon.png' alt='Icon2' class='icon_form' height='70' width='70'><input id='" . $name . "_glon' class='input_form_custom' type='text' name='glon' placeholder='Longitude' size=32 value='" . $glon . "' /></span>\n";

    print "</td></tr><tr><td width='60'>";                
    print "<input type='hidden' name='c' value='INSERT' />\n";
#    print '<span class="send_form">';
#    print "<script src='http://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_dg4Qj9EUNdnBicNW40nNoEJh' data-amount='0' data-name='Aamot Software' data-description='Piperpal Entry (1 dollar)' data-image='/img/Location_Icon.png'></script>";
    # print '<input class="custom_send_button" type="submit" value="PAY WITH CARD">';
#    print '</span>';
    print "</td></tr>";
    print "</table>";
    # print "<form action='http://www.piperpal.com/checkout.php?name=" . $name . "&service=" . $service . "' method='POST'>";
    # print '<span class="name_form input_form">';
    # print '<img src="img/icon1.png" alt="Icon1" style="margin-right:27px" class="icon_form" height="70" width="70">';
    # print '<input type="text" value="' . $name . '" id="' . $name . '" class="input_form_custom" name="name" placeholder="' . $name . '">';
    # print '</span>';
    # print '<br>';
    # print '<span class="website_form input_form">';
    # print '<img src="img/icon2.png" alt="Icon2" class="icon_form" height="70" width="70">';
    # print '<input type="text" value="' . $location . '" id="location" class="input_form_custom" name="location" placeholder="' . $location . '">';
    # print '</span>';
    # print '<br>';
    # print '<span class="service_form input_form">';
    # print '<img src="img/icon3.png" alt="Icon3" class="icon_form" height="70" width="70">';
    # print '<input type="text" value="' . $service . '" id="service" class="input_form_custom" name="service" placeholder="' . $service . '">';
    # print '</span>';
    # print "<span id='status_lns'>\n";
    # print "<span class='service_form input_form'>";
    # print '<img src="img/icon2.png" alt="Icon2" class="icon_form" height="70" width="70">';
    # print "<input id='glat' value='" . $glat . "' class='input_form_custom' type='text' name='glat' placeholder='" . $glat . "' size=16 /></span>\n";
    # print "<span class='service_form input_form'>";
    # print '<img src="img/icon2.png" alt="Icon2" class="icon_form" height="70" width="70">';
    # print "<input id='glon' value='" . $glon . "' class='input_form_custom' type='text' name='glon' placeholder='" . $glon . "' size=16 /></span>\n";
    # print "</span>\n";
    # print "<input type='hidden' name='c' value='INSERT' />\n";
    # print '<span class="send_form_item">';
    # print "<script src='http://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_odDlc1NMTUJdPN4WC2VTLvvu' data-amount='500' data-name='Aamot Software' data-description='" . $service . " (5 USD)' data-image='/img/icon2.png'></script>";
    # print '</span>';
    # print '</form>';

}

sub lns_market_item {
    my $c = CGI->new;
    # my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});

    my $name = shift(@_);
    my $location = shift(@_);
    my $service = shift(@_);
    my $glat = shift(@_);
    my $glon = shift(@_);
    my $modified = shift(@_);
    my $created = shift(@_);
    my $distance = shift(@_);
    print "<tr><td width=60>&nbsp;</td><td>";
    print "<form onsubmit='updateGeo()' id='lnsForm' name='lnsForm' action='https://api.piperpal.com/location/push.php' method='POST'>";
    # print '<span class="name_form input_form">';
    print "<location name='" . $name . "' href='" . $location . "' lat='" . $glat . "' lon='" . $glon . "'><a href='" . $location . "'>";
    print "<h4><a href='" . $location . "'>" . $name . "</a></h4></location>";
    print "<h5 style='color: #aaaadd'>" . $service . "</h5>";
    print "<h5>" . nearest(0.1, $distance) . " km away</h5>";
    print "<h6><a href='" . $location . "'>" . $location . "</a></h6>";
#    my $date = $created;
#    my $long = $modified;
#    my $dt = DateTime->now( time_zone => 'local' )->set_time_zone('floating');
#    print "<p><b>Created: " . $dt->subtract_datetime($date) . " days ago<br />";
#    print "Modified: "; print $dt->subtract_datetime($long) . " days ago</p>";
#    print "<p><b>";
    print "<table>";
    print "<tr><td width='60'>";
    print '<a href="/' . $name . '"><img src="/img/Name_Icon.png" title="Name of Location-aware Content Tag" height="70" width="70"></a>';
    print '</td><td><input type="text" id="' . $name .'" name="name" placeholder="Name" value="' . $name . '"></td></tr>';
  #  print '</span>';
#    print '<br>';
    #    print '<span class="website_form input_form">';
    print "<tr><td width='60'>";    
    print '<a href="' . $location . '"><img src="/img/Location_Icon.png" title="URL of Location-aware Content Tag" height="70" width="70"></a>';
    print '</td><td><input type="text" id="' . $name . '_location' . '" name="location" placeholder="http://" value="' . $location . '">';
 #   print '</span>';
 #    print '<br>';
    #    print '<span class="service_form input_form">';
    print "</td></tr><tr><td width='60'>";        
    print '<a href="/service/' . $service . '"><img src="/img/Service_Icon.png" title="Service type of Location-aware Content Tag" height="70" width="70"></a></td><td>';
    print '<select id="simple-search-location" class="input-large js-search-location" id="service" name="service" class=biginput><option selected value="' . $name . '.' . $service . '">' . $service . '</option><option value="Restaurant">Restaurant</option><option value="Bar">Bar</option><option value="Concert">Concert</option><option value="Film">Film</option><option value="Books">Books</option><option value="Health">Health</option><option value="Clothes">Clothes</option><option value="Food">Food</option><option value="Music">Music</option><option value="Electronics">Electronics</option><option value="Transport">Transport</option><option value="Rental">Rental</option></select>';
    print '<input type="hidden" id="paid_' . $name . '_service' . '" name="paid" placeholder="paid" value="0">';
    print "</td></tr><tr><td width='60'></td><td>";            
#    print '<span class="row row-condensed space-top-2 space-2">
#      <span class="col-sm-6">
#        <label for="simple-search-tourin" class="screen-reader-only">
#          Tour in
#        </label>
#        <input
#          id="datepicker"
#          type="text"
#          name="notBefore"
#          class="input-large tourin js-search-tourin"
#          placeholder="Not Before" value="' . $created . '">
#      </span>
#      <span class="col-sm-6">
#        <label for="simple-search-tourout" class="screen-reader-only">
#          Tour out
#          </label>
#        <input
#          id="datepicker"
#          type="text"
#          name="notAfter"
#          class="input-large tourout js-search-tourout"
#          placeholder="Not After" value="' . $modified . '">
#      </span>
#    </span>';
#    print '</span>';
    print "</td></tr><tr><td width='60'>";            
    print "<span id='status_lns'>\n";
#    print "<span class='service_form input_form'>";
    print "<img src='/img/Latitude_Icon.png' alt='Icon2' height='70' width='70'></td><td><input id='" . $name . "_glat' type='text' name='glat' placeholder='Latitude' size=35 value='" . $glat . "' />\n";
#</span>\n";

#    print "<span class='input_form_custom'><img src='img/Latitude_Icon.png' alt='Icon2' class='icon_form' height='70' width='70'><input id='" . $name . "_glat' class='input_form_custom' type='text' name='glat' placeholder='Latitude' size=32 value='" . $glat . "' /></span>\n";

    #   print "<span class='service_form input_form'>
    print "</td></tr><tr><td width='60'>";    
    print "<img src='/img/Longitude_Icon.png' alt='Icon2' height='70' width='70'></td><td><input id='" . $name . "_glon' type='text' name='glon' placeholder='Longitude' size=35 value='" . $glon . "' />\n";
#</span>\n";

 #   print "<span class='input_form_custom'><img src='img/Longitude_Icon.png' alt='Icon2' class='icon_form' height='70' width='70'><input id='" . $name . "_glon' class='input_form_custom' type='text' name='glon' placeholder='Longitude' size=32 value='" . $glon . "' /></span>\n";                             
    print "</td></tr><tr><td width='60'>";
    print "<img src='/img/Email_Icon.png' alt='Icon2' height='70' width='70'></td><td>";
    print "<input id='" . $name . "_expire' type='text' name='expire' placeholder='' size=35 value='" . $modified . "' />\n";
    print "</td></tr><tr><td width='60'>";                
    print "<img src='/img/Phone_Icon.png' alt='Icon2' height='70' width='70'></td><td>";       
    print "<input id='" . $name . "_expire' type='text' name='expire' placeholder='' size=35 value='" . $created . "' />\n";                                                                     print "</td></tr><tr><td width='60'>";
    print "<input type='hidden' name='c' value='INSERT' />\n";
#    print '<span class="send_form">';
#    print "<script src='http://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_dg4Qj9EUNdnBicNW40nNoEJh' data-amount='0' data-name='Aamot Software' data-description='Piperpal Entry (1 dollar)' data-image='/img/Location_Icon.png'></script>";
    # print '<input class="custom_send_button" type="submit" value="PAY WITH CARD">';
#    print '</span>';
    print "</td></tr>";
    print "</table>";
    # print "<form action='http://www.piperpal.com/checkout.php?name=" . $name . "&service=" . $service . "' method='POST'>";
    # print '<span class="name_form input_form">';
    # print '<img src="img/icon1.png" alt="Icon1" style="margin-right:27px" class="icon_form" height="70" width="70">';
    # print '<input type="text" value="' . $name . '" id="' . $name . '" class="input_form_custom" name="name" placeholder="' . $name . '">';
    # print '</span>';
    # print '<br>';
    # print '<span class="website_form input_form">';
    # print '<img src="img/icon2.png" alt="Icon2" class="icon_form" height="70" width="70">';
    # print '<input type="text" value="' . $location . '" id="location" class="input_form_custom" name="location" placeholder="' . $location . '">';
    # print '</span>';
    # print '<br>';
    # print '<span class="service_form input_form">';
    # print '<img src="img/icon3.png" alt="Icon3" class="icon_form" height="70" width="70">';
    # print '<input type="text" value="' . $service . '" id="service" class="input_form_custom" name="service" placeholder="' . $service . '">';
    # print '</span>';
    # print "<span id='status_lns'>\n";
    # print "<span class='service_form input_form'>";
    # print '<img src="img/icon2.png" alt="Icon2" class="icon_form" height="70" width="70">';
    # print "<input id='glat' value='" . $glat . "' class='input_form_custom' type='text' name='glat' placeholder='" . $glat . "' size=16 /></span>\n";
    # print "<span class='service_form input_form'>";
    # print '<img src="img/icon2.png" alt="Icon2" class="icon_form" height="70" width="70">';
    # print "<input id='glon' value='" . $glon . "' class='input_form_custom' type='text' name='glon' placeholder='" . $glon . "' size=16 /></span>\n";
    # print "</span>\n";
    # print "<input type='hidden' name='c' value='INSERT' />\n";
    # print '<span class="send_form_item">';
    # print "<script src='http://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_odDlc1NMTUJdPN4WC2VTLvvu' data-amount='500' data-name='Aamot Software' data-description='" . $service . " (5 USD)' data-image='/img/icon2.png'></script>";
    # print '</span>';
    # print '</form>';

}

sub is_valid {
    my $location = shift;
    my $ua = LWP::UserAgent->new;
    my $result = $ua->request(GET $location);
    print "is_valid.\n";
    print_r($result);
    return 0 if ($result==0);
    return 1 if (($result==1)||($result==2));
}

sub is_paid {
    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
    if ('GET' eq $c->request_method && $c->param('paid') eq "1" && $c->param('query') && $c->param('location')) {
   $dbh->do ("UPDATE piperpal SET paid = paid + 1, modified = NOW() WHERE name = '" . HTML::Entities::encode($c->param('query')) . "' and location = '" . $c->param('location') . "';");
    }
    return;
}

sub delete_location {
    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
    if ('GET' eq $c->request_method && $c->param('c') eq "DELETE" && $c->param('query') && $c->param('location') && $c->param('service')) {
   $dbh->do ("DELETE FROM piperpal WHERE name = '" . $c->param('query') . "' AND location = '" . $c->param('location') . "' AND service = '" . $c->param('service') . "';");
    }
    return;
}

sub insert_location {
    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
    if ('GET' eq $c->request_method && $c->param('c') eq "INSERT" && $c->param('query') && $c->param('location') && $c->param('service')) {
   # $dbh->do ("INSERT IGNORE INTO piperpal (name, location, service, glat, glon, modified, created, paid, token, type, email) VALUES ('" . $c->param('query') . "','" . $c->param('location') . "','" . $c->param('service') . "','" . $c->param('glat') . "','" . $c->param('glon') . "', NOW(), NOW(), 1, '" . $c->param('stripeToken') . "', '" . $c->param('stripeTokenType') . "','" . $c->param('stripeEmail') . "') ON DUPLICATE KEY UPDATE modified = NOW();");
    }
    return;
}

sub insert_publisher {
    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
    my $q;
    if ($c->request_method && $c->param('c') && $c->param('query') && $c->param('location') && $c->param('service')) {
   my @tags = ($c->param('query') =~ m/&(\w+)/g);
   my $name = $c->param('query');

   foreach my $tag (@tags)
   {
       next unless $tag =~ m/[a-zA-záäåāąæćčéēėęģíīįķļłńņðóöøōőŗśšúüūűųýźżžþ]/i;  
       $name =~ s{&$tag}{<a href="https://www.piperpal.com/register.cgi?name=$tag">&$tag</a>}g;
   }
   $q = "INSERT INTO piperpal (name, location, service, glat, glon, modified, created, paid, token, type, email) VALUES ('" . $name . "','" . $c->param('location') . "','" . $c->param('service') . "','" . $c->param('glat') . "','" . $c->param('glon') . "', NOW(), NOW(), 1, '" . $c->param('stripeToken') . "', '" . $c->param('stripeTokenType') . "','" . $c->param('stripeEmail') . "') ON DUPLICATE KEY UPDATE modified = NOW();";
   print $q;
   $dbh->do ($q);
    } else {
   # print "Error in inserting data.";
    }
    return;
}

sub update_location {
    my $c = CGI->new();
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
#    $dbh->{'mysql_enable_utf8'} = 1;
    if ($c->param('query')) {
   my $sth = $dbh->prepare ("SELECT name,location,service FROM piperpal WHERE (name LIKE '%" . HTML::Entities::encode($c->param('query')) . "%' OR service LIKE '%" . HTML::Entities::encode($c->param('query')) . "%') ORDER by modified DESC;");
   $sth->execute();
   while (my $ref = $sth->fetchrow_hashref()) {
       my @tags = ($ref->{'name'} =~ m/&(\w+)/g);
           foreach my $tag (@tags) {
               next unless $tag =~ m/[a-zA-záäåāąæćčéēėęģíīįķļłńņðóöøōőŗśšúüūűųýźżžþ]/i;  
               print "<form method='POST' action='adverts.cgi'>";
               print "<td>Word:</td><td><input type='name' name='" . $tag . "' value='" . $tag . "' /></td>";
               print "</form>\n";
           }
   }
   $sth->finish();
    }
    $dbh->disconnect();    
    return;
}

sub insert_advertiser {

    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
#    $dbh->{'mysql_enable_utf8'} = 1;
    if ('GET' eq $c->request_method && $c->param('c') eq "INSERT" && $c->param('query') && $c->param('location') && $c->param('service')) {
   
   my $sth = $dbh->prepare ("UPDATE piperpal SET location = '" . $c->param('location') . "', name = '" . HTML::Entities::encode($c->param('query')) . "', service = '" . $c->param('service') . "' = '" . $c->param('location') . "', service = '" . $c->param('service') . " WHERE name = '" . HTML::Entities::encode($c->param('query')) . "';");
   $sth->execute();
   while (my $ref = $sth->fetchrow_hashref()) {
       if (is_paid($ref->{'location'})) {
           print "<pre>UPDATE:The location of " . $ref->{'name'} . " " . $ref->{'location'} . " is a paid piperpal location.</pre>\n";
           $dbh->do ("UPDATE piperpal SET location = 'https://www.piperpal.com/index.cgi?name=" . $ref->{'name'} . "&service" . $ref->{'service'} . "&location=" . ($ref->{'location'}) . "&paid=0', paid = paid + 1, modified = NOW() WHERE name = '" . $ref->{'name'} . "';");
           print "<pre>Paid +1</pre>\n";
       } else {
           print "<pre>UPDATE:The location of " . $ref->{'name'} . " " . $ref->{'location'} . " is not a paid piperpal location.</pre>\n";
           $dbh->do ("UPDATE piperpal SET location = 'https://www.piperpal.com/index.cgi?name=" . $ref->{'name'} . "&service" . $ref->{'service'} . "&location=" . ($ref->{'location'}) . "&paid=-1', paid = paid - 1, modified = NOW() WHERE name = '" . $ref->{'name'} . "';");
           print "<pre>Paid -1</pre>\n";
       }
   $sth->finish();
   }
    }
    $dbh->disconnect();    
    return;
}

sub select_publisher {
    my $c = CGI->new;
    my $q;
    my $r;
    my $s;
    my $latitude;
    my $longitude;
    my $fp;
#    my $fn = "/home/4/p/piperpal/pull.csv";
#    my $string = "pull:" . $ENV{'REMOTE_ADDR'} . ":" . $q . "\n";    
    if ($c->param('query')) {
   $q = HTML::Entities::encode($c->param('query'));
# open(FH, '>', $fn) or die $!;
# print FH $string;
# print $fp;
# close($fp);
    } else {
   $q = "GoogleVisitorCenter";
    }
    if ($c->param('service')) {
   $s = $c->param('service');
    } else {
   $s = 'Search';
    }
    if ($c->param('radius')) {
   $r = $c->param('radius');
    } else {
   $r = 10;
    }
    if ($c->param('glat')) {
   $latitude = $c->param('glat');
    } else {
   # FIXME: READ LATITUDE FROM JAVASCRIPT
   $latitude = $ENV{'position.coords.latitude'};
# 37.8790153;
    }
    if ($c->param('glon')) {
   $longitude = $c->param('glon');
    } else {
   # FIXME: READ LONGITUDE FROM JAVASCRIPT
   $longitude = $ENV{'position.coords.longitude'};
#-122.26242529999999;
    }
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
#    $dbh->{'mysql_enable_utf8'} = 1;
    my $query = "SELECT name,location,glat,glon,modified,created,paid,token,type,email FROM piperpal WHERE (name LIKE '%" . HTML::Entities::encode($c->param('query')) . "%') ORDER by modified DESC;";
    $query = "SELECT DISTINCT id,name,location,service,modified,created,glat,glon,paid,token,type,email,3979*(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat)))) AS distance_in_km FROM piperpal JOIN (SELECT  " . $latitude . "  AS latpoint, " . $longitude . " AS longpoint) AS p ON 1=1 WHERE (name LIKE '%" . HTML::Entities::encode($c->param('query')) . "%') HAVING distance_in_km < " . $r . " ORDER BY distance_in_km ASC, modified DESC";
    my $sth = $dbh->prepare ($query);
    $sth->execute();
    print "<a name='results'><a href=\"https://www.piperpal.com/\"><img src='/piperpal.png' alt='piperpal.com Logo' width=\"320\" align=center/></a><br /><h3><a href=\"https://www.piperpal.com/\">Location Search Results</a></h3></a>";
    print "<ol>";
    print "<table>";
    while (my $ref = $sth->fetchrow_hashref()) {
   print "<tr><td width='60'>&nbsp;</td><td>";
   print "<form onsubmit='updateGeo()' method='GET' action='https://www.piperpal.com/cft/s/' id='formID'>";
   lns_market_item($ref->{'name'}, $ref->{'location'}, $ref->{'service'}, $ref->{'glat'}, $ref->{'glon'}, $ref->{'modified'}, $ref->{'created'}, $ref->{'distance_in_km'});
   print "<input type='submit' value='Submit Location for " . $ref->{'name'} . "'/>"; 
   print "</form>";
   print "</td></tr>";
    }
    print "</table>";
    print "</ol>";
    $sth->finish();
    $dbh->disconnect();
    return;
}

sub select_location {
    my $c = CGI->new;
    my $q;
    my $r;
    my $latitude;
    my $longitude;
    my $fp;
#    my $fn = "/home/4/p/piperpal/pull.csv";
#    my $string = "pull:" . $ENV{'REMOTE_ADDR'} . ":" . $q . "\n";    
    if ($c->param('query')) {
   $q = HTML::Entities::encode($c->param('query'));
# open(FH, '>', $fn) or die $!;
# print FH $string;
# print $fp;
# close($fp);
    } else {
   $q = "GoogleVisitorCenter";
    }
    if ($c->param('radius')) {
   $r = $c->param('radius');
    } else {
   $r = 1;
    }
    if ($c->param('glat')) {
   $latitude = $c->param('glat');
    } else {
   $latitude = 37.8790153;
    }
    if ($c->param('glon')) {
   $longitude = $c->param('glon');
    } else {
   $longitude = -122.26242529999999;
    }
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
#    $dbh->{'mysql_enable_utf8'} = 1;

#    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
#    $dbh->{'mysql_enable_utf8'} = 1;
    #my $sth = $dbh->prepare ("SELECT DISTINCT id,name,service,location,modified,created,glat,glon,paid,token,type,email,111.045*DEGREES(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat)))) AS distance_in_km FROM piperpal JOIN (SELECT  " . $latitude . "  AS latpoint, " . $longitude . " AS longpoint) AS p ON 1=1 WHERE paid > '0' AND name LIKE '%" . $q . "%' HAVING distance_in_km < " . $r . " ORDER BY distance_in_km");
    my $sth = $dbh->prepare ("SELECT DISTINCT name,location,service,glat,glon,modified,created,paid,token,type,email FROM piperpal WHERE modified < NOW() and created > NOW() ORDER by modified DESC, name ASC;");
    $sth->execute();
    while (my $ref = $sth->fetchrow_hashref()) {
   #print "<h3><a href='https://www.piperpal.com/" . $ref->{'name'}  . "'>" . $ref->{'name'} . "</a></h3>";
   print "<form onsubmit='updateGeo()' method='GET' action='https://www.piperpal.com/cft/s/' id='formID'>";        
   lns_market_item($ref->{'name'}, $ref->{'location'}, $ref->{'service'}, $ref->{'glat'}, $ref->{'glon'}, $ref->{'modified'}, $ref->{'created'});
   print "<input type='submit' value='Submit Location for " . $ref->{'name'} . "'/>";
   print "</form>\n";
    }
    $sth->finish();    
    $dbh->disconnect();
    return;
}

sub select_market {
    my $c = CGI->new;
    my $q;
    my $r;
    my $latitude;
    my $longitude;
    if ($c->param('query')) {
   $q = HTML::Entities::encode($c->param('query'));
    } else {
   $q = "GoogleVisitorCenter";
    }
    if ($c->param('radius')) {
   $r = $c->param('radius');
    } else {
   $r = 25;
    }
    if ($c->param('glat')) {
   $latitude = $c->param('glat');
    } else {
   $latitude = 37.8790153;
    }
    if ($c->param('glon')) {
   $longitude = $c->param('glon');
    } else {
   $longitude = -122.26242529999999;
    }
    my $dbh = DBI->connect("DBI:mysql:database=piperpalcom02;host=piperpalcom02.mysql.domeneshop.no", "piperpalcom02", "xxxxxxxx", {'RaiseError' => 1});
#    $dbh->{'mysql_enable_utf8'} = 1;
    my $query = "SELECT name,location,service,glat,glon,modified,created,paid,token,type,email FROM piperpal WHERE (name LIKE '%" . $q . "%' OR service LIKE '%" . $q . "%') AND paid > '0' ORDER by modified;";
    $query = "SELECT DISTINCT id,name,location,modified,created,glat,glon,paid,token,type,email,3979*(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat)))) AS distance_in_km FROM piperpal JOIN (SELECT  " . $latitude . "  AS latpoint, " . $longitude . " AS longpoint) AS p ON 1=1 WHERE (name LIKE '%" . $q . "%') HAVING distance_in_km < " . $r . " ORDER BY distance_in_km,modified";
    my $sth = $dbh->prepare ($query);
    $sth->execute();
#    print "</td></tr></table><table><tr><td>";
    while (my $ref = $sth->fetchrow_hashref()) {
   print "<form onsubmit='updateGeo()' id='lnsForm' name='lnsForm' action='https://api.piperpal.com/location/push.php' method='POST'>";
# print "<table><tr><td width='60'>&nbsp;</td><td>";
   lns_market_item($ref->{'name'}, $ref->{'location'}, $ref->{'service'}, $ref->{'glat'}, $ref->{'glon'}, $ref->{'modified'}, $ref->{'created'}, $ref->{'distance_in_km'});
   print "<input type='submit' value='Submit Location for " . $ref->{'name'} . "'/>";
# print "</td></tr></table>";
   print "</form>";
    }
    print "</td></tr></table>";
    $sth->finish();    
    $dbh->disconnect();
    return;
}

Query Interface on World Wide Web - www.piperpal.com

Our working implementation of "Location Search on World Wide Web" is on http://www.piperpal.com/.

Source: https://www.piperpal.com/index.cgi

#!/usr/bin/perl

# Copyright (C) 2015, 2019  Aamot Software
#
# Author: ole@aamotsoftware.com
#
# Date: 2015-09-03T11:15:00+01
#
# Field: Incremental, location, sql, perl
#
# URL: https://www.piperpal.com/index.cgi

use strict;
use warnings;
use DBI;
use CGI qw/:standard/;
use CGI::Cookie;
use lib '..';
use Piperpal;

my $c = CGI->new;
print "Content-Type: text/html\n\n";
print <<EOF;
<!DOCTYPE html>
<html lang="en">
    <head>
    <style>
    #name label{
    display: inline-block;
    width: 100px;
    text-align: right;
    }
    #name_submit{
    padding-left: 100px;
    }
    #name div{
    margin-top: 1em;
    }
    textarea{
    vertical-align: top;
    height: 5em;
    }

    .error{
    display: none;
    margin-left: 10px;
    }

    .error_show{
    color: red;
    margin-left: 10px;
    }

    input.invalid, textarea.invalid{
    border: 2px solid red;
    }

    input.valid, textarea.valid{
    border: 2px solid green;
    }
    </style>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="iso-8859-1">

    <!--[if IE 8]>
      <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->
   <!--[if !(IE 8)]><!-->
      <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
    <!--<![endif]-->

    <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->

    <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
  <!--[if IE 7]>
    <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
  <!--[if IE 6]>
    <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
    <![endif]-->
    <!-- FIXME-->
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
    <!--FIXME -->
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    <meta name="viewport" content="user-scalable=yes, initial-scale=1.0, maximum-scale=3, minimum-scale=0.5, width=device-width">
    <!--
    <link rel="dns-prefetch" href="//maps.googleapis.com">
    -->
    <link rel="dns-prefetch" href="//maps.gstatic.com">
    <link rel="dns-prefetch" href="//mts0.googleapis.com">
    <link rel="dns-prefetch" href="//fonts.googleapis.com">
    <link rel="dns-prefetch" href="//www.piperpal.com">
    <title>piperpal.com - Location-based Search Engine</title>
    <link href="my_style_form.css" type="text/css" rel="stylesheet" />
    <link href='https://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
    <link href='https://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
    <meta charset="iso-8859-1" />
    <script>
    function price_changed() {
        var priceWidget = document.getElementById('price');
        var price = priceWidget.options[priceWidget.selectedIndex].value;
        var stripeSubmit = document.getElementsByClassName('stripe-button-el')[0];
        var regularSubmit = document.getElementById('regular-submit');
        if (price > 0) {
            stripeSubmit.style.display = 'inline-block';
            regularSubmit.style.display = 'none';
        } else {
            stripeSubmit.style.display = 'none';
            regularSubmit.style.display = 'inline-block';
        }
}

function updateGeo() {
    var glat = document.getElementById("glat");
    var glon = document.getElementById("glon");
    
    glat.value = position.coords.latitude;
    glon.value = position.coords.longitude;

    alert(glat+","+glon);
}

function getWikipedia() {
    jQuery(function($) {
        $.getJSON('https://api.geonames.org/findNearbyWikipediaJSON?formatted=true&lat='+ position.coords.latitude +'&lng='+ position.coords.longitude +'&username=username&style=full&lang=en&wikipediaUrl&thumbnailImg', function(json){

            for(var i = 0; i < json.geonames.length; i++)
            {
                $("#wikipedia").prepend('<span style="font-family: geneva, arial, helvetica, sans-serif;"><br><br><img src="wikilogo.gif"><br>' + json.geonames[i].summary + '<br><a href="https://'+ json.geonames[i].wikipediaUrl +'" target="_blank">'+ json.geonames[i].wikipediaUrl +'</a><br></span>');
                  }
            }); });
}

function submit() {
        // Strip hijacks the form submit, so we need to un-hijack it.
            var form = document.getElementById('form');
        form.submit();
}
    </script>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" >
    <meta http-equiv="X-UA-Compatible" content="IE=edge" >
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>

    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

    <script type="text/javascript" src="https://www.piperpal.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="https://www.piperpal.com/jquery.autocomplete.min.js"></script>
    <!-- FIXME -->
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-names.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-services.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-locations.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-queries.php"></script>
    <!-- FIXME -->
    <meta name="viewport" content="user-scalable=yes, initial-scale=1.0, maximum-scale=3, minimum-scale=0.5, width=device-width">
    <script>
    \$(function() {
        \$( "#datepicker" \)\.datepicker\(\)\;
        \$( "#simple-search-tourout" \)\.datepicker\(\)\;
    \}\)\;
    </script>
    <meta name="viewport" content="user-scalable=yes, initial-scale=1.0, maximum-scale=3, minimum-scale=0.5, width=device-width">         
    </head>
    <body style="background: #ffffff;" onload="document.getElementById('query').focus();">

    <!--
    <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=true"></script>-->
    <!--script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"--><!--/script-->
    <script>
        function success(position) {
        var s = document.querySelector('#status');
        
        if (s.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        s.innerHTML = '<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
        s.className = 'success';

        var q = document.querySelector('#status_publisher');
        
        if (q.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        q.innerHTML = '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

        // '<input type=text name=glat size=16 value=' + position.coords.latitude + ' /><input type=text name=glon size=16 value=' + position.coords.longitude + ' />';
        q.className = 'success';

        var r = document.querySelector('#status_lns');
        
        if (r.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        r.innerHTML =  '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

//'<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
        r.className = 'success';

        var mapcanvas = document.createElement('div');
        mapcanvas.id = 'mapcanvas';
        mapcanvas.style.height = '400px';
        mapcanvas.style.width = '640px';
        
        document.querySelector('article').appendChild(mapcanvas);
        
        var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
        var myOptions = {
        zoom: 15,
        center: latlng,
        mapTypeControl: false,
        navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
        mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
        
        var marker = new google.maps.Marker({
                position: latlng, 
                                map: map, 
                                title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
                                });

        var locations = [
         ['Banja Luka', 44.766666699999990000, 17.183333299999960000, 4],
    ['Tuzla', 44.532841000000000000, 18.670499999999947000, 5],
    ['Zenica', 44.203439200000000000, 17.907743200000027000, 3],
    ['Sarajevo', 43.850000000000000000, 18.250000000000000000, 2],
    ['Mostar', 43.333333300000000000, 17.799999999999954000, 1]
];

var infowindow = new google.maps.InfoWindow();

var marker, i;
for (i = 0; i < locations.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][1], locations[i][2]),
      map: map
                                    });

google.maps.event.addListener(marker, 'click', (function (marker, i) {
    return function () {
        infowindow.setContent(locations[i][0]);
        infowindow.open(map, marker);
    }
                                                })(marker, i));
}
}

function error(msg) {
        // var s = document.querySelector('#status');
        // s.innerHTML = typeof msg == 'string' ? msg : "failed";
        // s.className = 'fail';
        
        // console.log(arguments);
}

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(success, error);
} else {
        error('not supported');
}

</script>

    <center><table border='0'><tr><td valign='top' width='100%' align='center'><a href="https://www.piperpal.com/"><img src='/piperpal.png' alt='piperpal.com Logo' width="320" align=center/></a></td></tr>
    
    <div class="background_form">
EOF

print "<tr><td valign='top' width='100%' align='center'>";
#print "<h3>Discover the world around you in <span id='countdowntimer'></span> seconds</h3>";
print "<script type='text/javascript'>";
print "function increase(){";
print "            var counterElement = document.getElementById(\"countdowntimer\");";
print "            var counter = counterElement.textContent;";
print "            counter++;";
print "            counterElement.innerHTML = counter;";
print "        }";
print "        window.onload = increase;";
print "</script>";
#print "<h4>12 Million Locations at Your Fingertips</h4>";
#print "<label for=\"countdowntimer\">Location Search progress</label>";
#print "<progress id=\"countdowntimer\" max=\"50\">10%</progress>";
#print "<script type=\"text/javascript\" src=\"https://api.piperpal.com/location/json.php?service=Restaurant&glat=' + position.coords.longitude + '&glon=' + position.coords.longitude + '\"></script>\n";
#print "<script language=\"JavaScript\">\n";
#print "var obj = JSON.parse(locations);\n";
#print "for (i=0; i < obj.locations.length; i++) {\n";
#print "document.write(\"<h1>\" + obj.locations[i].name + \"</h1><h2><a href='\" + obj.locations[i].location + \"'>\" + obj.locations[i].location + \"</a> (\" + obj.locations[i].distance + \")</h2><h3>\" + \" \" + obj.locations[i].service + \" \" + \"</h3>\n\");\n";
#print "<!--document.write(\"<p>\" + obj.locations[i].distance + \"</p><form method='GET' action='/search.php#results'><input type='text' name='name' placeholder='' value='\" + obj.locations[i].name + \"'/><input type='hidden' name='glat' value='\" + obj.locations[i].glat + \"' /><input type='hidden' name='glon' value='\" + obj.locations[i].glon + \"'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />\"); -->\n";
#print "}\"\n";
#print "</script>\n";
#print "<h3>It\'s not where you\'re from, it\'s where you\'re at</h3>";
#print "<p><a href=\"https://www.piperpal.com/tutorial/\">Piperpal 4.0 Tutorial</a></p>";
# print "<p>The Piperpal implementation of Location Search for World Wide Web<br />is described in <a href=\"https://www.piperpal.com/thesis.pdf\">https://www.piperpal.com/thesis.pdf</a> ready for 2026.</p>";
&Piperpal::input_searchers($c);
# print "<a name='results'><a href=\"https://www.piperpal.com/\"><img src='/piperpal.png' alt='piperpal.com Logo' width=\"320\" align=center/></a><br />
#<h3><a href=\"https://www.piperpal.com/\">Location Search Results</a></h3></a>";
&Piperpal::select_publisher();
print "<br />";
print "<br />";
print "<br />";
print "<br />";
print "<br />";
print "<p>You could markup with &lt;location&gt; tag in <a href='https://www.w3.org/wiki/HTML/next#.3Clocation.3E_element_.28like_.29_for_expressing_geo_information.2C_eg_with_attributes_lat.2C_long.2C_altitude'>HTML</a><br />";
print "<a href=\"https://www.aamotsoftware.com/location.html\">https://www.aamotsoftware.com/location.html</a></p>";
print "<p><a href=\'https://www.stripe.com/\'><img alt=\'Powered by stripe\' src=\'/powered_by_stripe.png\'></a>&nbsp;<a href=\'https://play.google.com/store/apps/details?id=com.piperpal.api.android&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play\' src=\'/google-piperpal.png\'/></a></p>";
print "<p>Copyright &copy; 2015-2023  <location name='Aamot Software' href='https://www.aamotsoftware.com/' lat='37.4219999' lon='-122.0862462' service='Electronics'>Aamot Software</location><br /><location name='Piperpal' href='https://www.piperpal.com/' lat='59.94215220' lon='10.71697530' service='Crawler'>Oslo, Norway</location> - <location name='Piperpal' href='https://www.piperpal.com/' lat='37.879015' lon='-122.262425' service='Crawler'>Berkeley, California, USA</location></p>";
#print "<h2>Wikipedia Location-aware Content</h2>";
#&Piperpal::insert_wikipedia();
#print "</td></tr><tr><td valign='top' width=512>";
#print "<h3>Be discovered by the world around you</h3>";
#print "<p>Submit entries in Piperpal\'s Location-aware Search Engine</p>";
#&Piperpal::input_publisher();
#&Piperpal::insert_publisher();
print '<h3>News</h3>';
print '<p><b>2023</b></p>';
print '<p><a href="https://piperpal.com/">Piperpal</a>\'s Where do you think? feature is now active.  You need a VISA/MasterCard to add new locations at $0.01 USD at <a href="https://www.piperpal.com/google.html">https://www.piperpal.com/google.html</a></p>';
print '<a href="https://www.piperpal.com/"><img src="/piperpal.png" alt="piperpal.com Logo" width="320" align="center/"></a><form id="form" method="GET" action="https://www.piperpal.com/cft/s/"><table><tr><td>Text: <input id="name" type="text" name="name" placeholder="Example: &HappyJuly4th" size="24" /><span class="error">This field is required</span></td></tr><tr><td>Email: <input id="email" type="text" name="email" placeholder="your.name@gmail.com" /><span class="error">This field is required</span></td></tr><tr><td>Service: <select id="service" name="service"><option value="Restaurant">Restaurant</option><option value="Bar">Bar</option><option value="Concert">Concert</option><option value="Film">Film</option><option value="Books">Books</option><option value="Health">Health</option><option value="Clothes">Clothes</option><option value="Food">Food</option><option value="Music">Music</option><option value="Electronics">Electronics</option><option value="Transport">Transport</option><option value="Rental">Rental</option></select></td></tr><tr><td>Location: <input type="text" name="location" placeholder="https://yourwebsite.com/" /></td></tr><!--<tr><td>Latitude: <input type="text" name="glat" value="37.4375596"></td></tr><tr><td>Longitude: <input type="text" name="glon" value="-122.11922789999998"></td></tr>--><tr><td>Payment (¢): <input type="currency" name="paid" value="1" placeholder="Type a price"></td></tr><tr><td><input type="submit" name="Submit" value="Submit" /></td></tr></table></form>';
print '<p><b>2022</b></p>';
print '<p><a href="https://www.aamotsoftware.com/">Aamot Software</a>\'s Location Entries can be ordered for $0.42 USD per location at <a href="https://www.piperpal.com/cft/s/">https://www.piperpal.com/cft/s/</a>';
print '<p><b>2021</b></p>';    
print '<p><a href="https://www.aamotsoftware.com/">Aamot Software</a>\'s second functional example of HTML with location tagging and fetching was stored on <a href="https://piperpal.com/google.html">https://piperpal.com/cft/s/</a></p>';
print '<p><b>2020</b></p>';
print '<p><a href="https://www.aamotsoftware.com/">Aamot Software</a>\'s Indexer for Piperpal written in the programming language Python can now recursively index location tags as specified on <a href="https://www.aamotsoftware.com/location.html">https://www.aamotsoftware.com/location.html</a> from web pages that are listed for such indexing on <a href="https://www.aamotsoftware.com/location-source.html">https://www.aamotsoftware.com/location-source.html</a></p>';
print '<p><b>2015</b></p>';    
print '<p><a href="https://www.aamotsoftware.com/">Aamot Software</a>\'s first practical example of location tagging with Piperpal was stored on <a href="https://piperpal.com/Googleplex">https://piperpal.com/Googleplex</a> at a lunch table with <a href="https://www.norvig.com/">Peter Norvig</a> in the Googleplex in Mountain View, California in 2015 where he mentioned crowd sourcing of location tags with a neural network filter as future work.</p>';
print '<p><a href="https://www.aamotsoftware.com/">Aamot Software</a>\'s presentation for <a href="https://research.google.com/">Google Research</a>: <a href="https://www.piperpal.com/doc/3.0/Piperpal-Location-aware-ContentTag.pdf">Location-aware Content Tag: &lt;location&gt;,&location markup</a></p>';
#<tr><td width=60>&nbsp;</td><td><p>Copyright &copy; 2015-2022 <a href='https://www.aamotsoftware.com/'>Ole Aamot Software</a>";
print "</td></tr></table>\n";
#print "<p>Copyright &copy; 2018 <a href=\"https://www.aamotsoftware.com/\">Ole Aamot Software</a></p>";
print "</body>\n</html>\n";

Query Interface API on World Wide Web - api.piperpal.com

Source: https://api.piperpal.com/index.php

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <meta charset="utf-8">
    <title>Piperpal</title>
  </head>
  <body>
    <div id="log"></div>   
    <script>
         $(document).ready(function(){
                         
                         setInterval(function(){
                                         
                                         if (navigator.geolocation) {
                                                 navigator.geolocation.getCurrentPosition(ajaxCall);         
                                         } else{
                                                 $('#log').html("GPS is not available");
                                         }
                                         
                                         function ajaxCall(position){
                                                 
                                                 var latitude = position.coords.latitude;
                                                 var longitude = position.coords.longitude;
                                                 var location = window.location.pathname.substr(1);
                                                 var queryString = window.location.search;
                                                 var urlParams = new URLSearchParams(queryString);
                                                 // alert(queryString+":("+latitude+","+longitude+")");
                                                 $.ajax({
                                                         url: "https://api.piperpal.com/pull.php", 
                                                                         type: 'POST', //I want a type as POST
                                 data: {'glat' : latitude, 'glon' : longitude, 'location' : location, 'name' : urlParams.get('name'), 'service' : urlParams.get('service'), 'radius' : urlParams.get('radius') },
                                                                         success: function(response) {
                                                                                 $('#log').html(response);
                                                                                 // alert(response);
                                                                 }
                                                   });
                                   }       
                           },15000);
                   

                 });
    </script>
          <h2>Documentation</h2>
          <h3>Location JavaScript API</h3>
          <h4>Pull</h4>
          <pre>
            &lt;script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=37.4375596&glon=-122.11922789999998"&gt;&lt;/script&gt;
          </pre>
          <h4>Push</h4>
          <pre>
            <span style="color: #ff0000">Example</span>
            https://api.piperpal.com/location/push.php?name=<span style="color: #ff0000">Google</span>&location=<span style="color: #ff0000">http://www.google.com/</span>&service=<span style="color: #ff0000">Books</span>&glat=<span style="color: #ff0000">37.4375596</span>&glon=<span style="color: #ff0000">-122.11922789999998</span>&paid=<span style="color: #ff0000">50</span>
          </pre>
          <p>&copy; 2022 Aamot Software</p>
  </body>
</html>

Source: https://api.piperpal.com/pull.php


<?php
$db = mysqli_connect("piperpal.mysql.domeneshop.no","piperpal","xxxxxxxx","piperpal");
$query = "SELECT DISTINCT id,name,service,location,modified,created,glat,glon,paid,token,type,email,111.045*DEGREES(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat)))) AS distance_in_km FROM piperpal JOIN (SELECT  " . $_POST['glat'] . "  AS latpoint, " . $_POST['glon'] . " AS longpoint) AS p ON 1=1 WHERE name = '%" . $_POST['name'] . "%' OR service LIKE '%" . $_POST['service'] . "%' HAVING distance_in_km < " . $_POST['radius'] . " ORDER BY distance_in_km ASC, modified DESC";
$result = $db->query($query);
$num_coords = mysqli_num_rows($result);
if ($num_coords == 0) {
    print "<form onsubmit='updateGeo()' id='lnsForm' name='lnsForm' action='https://www.piperpal.com/checkout.php' method='POST'>";
    print "<input type='hidden' name='c' value='INSERT' />\n";
    print "<table cellpadding=5><tr>";
    print "<td><a href='http://piperpal.com/" . $_POST['name'] . "'><img border=0 width=16 height=16 src='/js-icon.png' /></td>";
    print "<td><input size=16 type=text name=name class=biginput id=name placeholder='Name' value='" . $_POST['name'] . "' /></td>\n";
    print "<td><input size=20 type=text name=location class=biginput id=location placeholder='http://' value='" . $_SERVER['HTTP_REFERER'] . "' /></td>\n";
    print "<td><input size=16 type=text name=service class=biginput id=service placeholder='Service' value='" . $_POST['service'] . "' /></td>\n";
    print "<div id='status'><input type='hidden' name='glat' placeholder='Latitude' size=16 value='" . $_POST['glat'] . "' /><input type='hidden' name='glon' placeholder='Longitude' size=16 value='" . $_POST['glon'] . "' /></div>\n";
    print "<td><form action='' method='POST'><script src='https://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_9UbKhDJJWaAFnMjYQTBA8I9i00H8Z5eMmL' data-amount='43' data-name='Aamot Software' data-description='Piperpal &" . $_POST['name'] . "%" . $_POST['service'] . " (USD 0.43)' data-image='/128x128.png'></script></td>";
    print "</tr>\n";
    print "</form>\n";
} else {
    print "var locations = '{ \"locations\" : [' + '";
  while($object = mysqli_fetch_object($result)) {
    print "    { id: '" . $object->id . "', name: '" . $object->name . "', service: '" . $object->service . "', location: '" . $object->location . "', modified: '" . $object->modified . "', created: '" . $object->created . "', glat: '" . $object->glat . ", glon: '" . $object->glon . ", distance: '" . $object->distance_in_km . "', paid: '" . $object->paid . "', token: '" . $object->token . "', type: '" . $object->type . "', email: '" . $object->email . "' }\n";
  }
  print "]};";
}
?>

Location Search on World Wide Web - www.piperpal.com/location

Source: https://www.piperpal.com/location/index.html

<html>
<body onload="updateGeo();">
  <h1>Location</h1>
  <script>
    pt>
    var x = document.getElementById("demo");
    function getLocation() {
    if (navigator.geolocation) {
       navigator.geolocation.getCurrentPosition(showPosition);
     f();       
    } else {
     x.innerHTML = "Geolocation is not supported by this browser.";
    }
    }
    function f() {
     // Update every 1 ms seconds
     var options = {enableHighAccuracy: true,timeout: 5000,maximumAge: 0,desiredAccuracy: 0, frequency: 1 };
    watchID = navigator.geolocation.watchPosition(onSuccess, onError, options);
     getLocation();
    }
    function showPosition(position) {
     x.innerHTML = "Latitude: " + position.coords.latitude +
         "<br>Longitude: " + position.coords.longitude;
     window.location.href="https://www.piperpal.com/location/?glat=" + position.coords.latitude + "&glon=" + position.coords.longitude;
    }
  </script>
  <script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Restaurant&glat=' + position.coords.longitude + '&glon=' + position.coords.longitude + '"></script>
  <script language="JavaScript">
    var obj = JSON.parse(locations);
    for (i=0; i < obj.locations.length; i++) {
     document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
         <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
    }
    </script>
  <location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
  <location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
    <p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
  </location>
</body>
</html>

Source: https://www.piperpal.com/location/location.html

<script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=' + position.coords.longitude + '&glon=' + position.coords.longitude + '"></script>
<script language="JavaScript">
var obj = JSON.parse(locations);
for (i=0; i < obj.locations.length; i++) {
   document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
   <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
}
</script>
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
<p>Check out <a href="https://www.geopher.com/paloalto.html">Palo Alto</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
</location>

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="utf-8">

    <!--[if IE 8]>
      <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->
   <!--[if !(IE 8)]><!-->
      <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
    <!--<![endif]-->

    <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->

    <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
  <!--[if IE 7]>
    <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
  <!--[if IE 6]>
    <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
    <link rel="dns-prefetch" href="//maps.googleapis.com">
    <link rel="dns-prefetch" href="//maps.gstatic.com">
    <link rel="dns-prefetch" href="//mts0.googleapis.com">
    <link rel="dns-prefetch" href="//fonts.googleapis.com">
    <link rel="dns-prefetch" href="//www.piperpal.com">
    <title>piperpal.com - Location-based Search Engine</title>
    <link href="my_style_form.css" type="text/css" rel="stylesheet" />
    <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
    <meta charset="utf-8" />
    <script>
    function price_changed() {
        var priceWidget = document.getElementById('price');
        var price = priceWidget.options[priceWidget.selectedIndex].value;
        var stripeSubmit = document.getElementsByClassName('stripe-button-el')[0];
        var regularSubmit = document.getElementById('regular-submit');
        if (price > 0) {
       stripeSubmit.style.display = 'inline-block';
       regularSubmit.style.display = 'none';
        } else {
       stripeSubmit.style.display = 'none';
       regularSubmit.style.display = 'inline-block';
        }
}

function updateGeo() {
    var glat = document.getElementById("glat");
    var glon = document.getElementById("glon");
    
    glat.value = position.coords.latitude;
    glon.value = position.coords.longitude;

    alert(glat+","+glon);
}

function getWikipedia() {
    jQuery(function(127416 127416 {
   0getJSON('http://api.geonames.org/findNearbyWikipediaJSON?formatted=true&lat='+ position.coords.latitude +'&lng='+ position.coords.longitude +'&username=username&style=full&lang=en&wikipediaUrl&thumbnailImg', function(json){

       for(var i = 0; i < json.geonames.length; i++)
       {
           127416 127416"#wikipedia").prepend('<span style="font-family: geneva, arial, helvetica, sans-serif;"><br><br><img src="wikilogo.gif"><br>' + json.geonames[i].summary + '<br><a href="http://'+ json.geonames[i].wikipediaUrl +'" target="_blank">'+ json.geonames[i].wikipediaUrl +'</a><br></span>');
             }
       }); });
}

function submit() {
        // Strip hijacks the form submit, so we need to un-hijack it.
       var form = document.getElementById('form');
        form.submit();
}
    </script>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
    <meta http-equiv="X-UA-Compatible" content="IE=edge" >
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>

    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

    <script type="text/javascript" src="https://www.piperpal.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="https://www.piperpal.com/jquery.autocomplete.min.js"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-names.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-services.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-locations.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-queries.php"></script>
    <meta name="viewport" content="width=100%" />
    <script>
    $(function() {
 $( "#datepicker" ).datepicker();
 $( "#simple-search-tourout" ).datepicker();
    });
    </script>
    <meta name="viewport" content="width=100%, initial-scale=1.0">         
    </head>
    <body style="background: #ffffff;" onload="document.getElementById('query').focus();">
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <!--script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"--><!--/script-->
    <script>
 function success(position) {
 var s = document.querySelector('#status');
 
 if (s.className == 'success') {
         // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
         return;
 }
 
        s.innerHTML = '<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
 s.className = 'success';

 var q = document.querySelector('#status_publisher');
 
 if (q.className == 'success') {
         // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
         return;
 }
 
        q.innerHTML = '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

        // '<input type=text name=glat size=16 value=' + position.coords.latitude + ' /><input type=text name=glon size=16 value=' + position.coords.longitude + ' />';
 q.className = 'success';

 var r = document.querySelector('#status_lns');
 
 if (r.className == 'success') {
         // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
         return;
 }
 
        r.innerHTML =  '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

//'<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
 r.className = 'success';

 var mapcanvas = document.createElement('div');
 mapcanvas.id = 'mapcanvas';
 mapcanvas.style.height = '400px';
 mapcanvas.style.width = '640px';
 
 document.querySelector('article').appendChild(mapcanvas);
 
 var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
 var myOptions = {
 zoom: 15,
 center: latlng,
 mapTypeControl: false,
 navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
 mapTypeId: google.maps.MapTypeId.ROADMAP
 };
 var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
 
 var marker = new google.maps.Marker({
         position: latlng, 
                         map: map, 
                         title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
                         });

        var locations = [
         ['Banja Luka', 44.766666699999990000, 17.183333299999960000, 4],
    ['Tuzla', 44.532841000000000000, 18.670499999999947000, 5],
    ['Zenica', 44.203439200000000000, 17.907743200000027000, 3],
    ['Sarajevo', 43.850000000000000000, 18.250000000000000000, 2],
    ['Mostar', 43.333333300000000000, 17.799999999999954000, 1]
];

var infowindow = new google.maps.InfoWindow();

var marker, i;
for (i = 0; i < locations.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][1], locations[i][2]),
      map: map
                             });

google.maps.event.addListener(marker, 'click', (function (marker, i) {
    return function () {
 infowindow.setContent(locations[i][0]);
 infowindow.open(map, marker);
    }
                                         })(marker, i));
}
}

function error(msg) {
 // var s = document.querySelector('#status');
 // s.innerHTML = typeof msg == 'string' ? msg : "failed";
 // s.className = 'fail';
 
 // console.log(arguments);
}

if (navigator.geolocation) {
 navigator.geolocation.getCurrentPosition(success, error);
} else {
 error('not supported');
}

</script>

    <center><table border='0'><tr><td valign='top' width='100%' align='center'><a href="https://www.piperpal.com/"><img src='/piperpal.png' alt='piperpal.com Logo' width="320" align=center/></a></td></tr>
    
    <div class="background_form">
<tr><td valign='top' width='100%' align='center'><h3>Discover the world around you</h3><form onsubmit='updateGeo()' method='GET' action='https://www.piperpal.com/' id='formID'><table><tr><td><center><input size="30" type="text" class="input_form_custom" id="query" name="query" placeholder="Enter keyword" /></center></td></tr><tr><td><select size="12" id="service" name="service"><option value="Restaurant">Restaurant</option><option value="Bar">Bar</option><option value="Concert">Concert</option><option value="Film">Film</option><option value="Books">Books</option><option value="Health">Health</option><option value="Clothes">Clothes</option><option value="Food">Food</option><option value="Music">Music</option><option value="Electronics">Electronics</option><option value="Transport">Transport</option><option value="Rental">Rental</option></select></td><td><select size="12" name="radius" id="radius" class="input_form_custom"><option value='40075' selected>40075 km</option><option value='30000'>30000 km</option><option value='20000'>20000 km</option><option value='10000'>10000 km</option><option value='9000'>9000 km</option><option value='8000'>8000 km</option><option value='7000'>7000 km</option><option value='6000'>6000 km</option><option value='5000'>5000 km</option><option value='4000'>4000 km</option><option value='3000'>3000 km</option><option value='2500'>2500 km</option><option value='2000'>2000 km</option><option value='1500'>1500 km</option><option value='1250'>1250 km</option><option value='1000'>1000 km</option><option value='750'>750 km</option><option value='500'>500 km</option><option value='250'>250 km</option><option value='100'>100 km</option><option value='50'>50 km</option><option value='25'>25 km</option><option value='10'>10 km</option><option value='5'>5 km</option><option value='2'>2 km</option><option value='1'>1 km</option></select></td><td>&nbsp;</td><td><input type="submit" id="search" name="search" value="Go" /></td></tr></table><span id='status'><input type='hidden' name='glat' /><input type='hidden' name='glon' /></span>
</form><br>
<script language="javascript" type="text/javascript">                           
var glat_var = position.coords.latitude;                                        
</script>                                                                       
<a href="location.html" onclick="location.href=this.href+'?glat='+glat_var;retur
                        n false;">Link</a>                                                              
<script type="text/javascript" src="https://api.piperpal.com/location/json.php?s
ervice=Books&glat=' + position.coords.longitude + '&glon=' + position.coords.lon
gitude + '"></script>                                                           
<script language="JavaScript">                                                  
var obj = JSON.parse(locations);                                                
for (i=0; i < obj.locations.length; i++) {                                      
    document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.lo
                    cations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.location
                    s[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n")
            ;                                                                               
       <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET
                       ' action='/search.php'><input type='text' name='name' placeholder='' value='" + 
                       obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.loca
                       tions[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i
                       ].glon + "'/><span id='geopher'></span><select name='service'><option value='Foo
                       d'>Food</option><option selected value='Search'>Search</option></select><input t
                       ype='submit' value='Search' /><br />"); -->                                     
}                                                                               
</script>                                                                       
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="
59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-
31 12:00:00" paid="50" />                                                       
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http
://berkeley.edu/">
<cript type="text/javascript" src="https://api.piperpal.com/location/json.php?se
rvice=Books&glat=' + position.coords.longitude + '&glon=' + position.coords.long
itude + '"></script>                                                            
<script language="JavaScript">                                                  
var obj = JSON.parse(locations);                                                
for (i=0; i < obj.locations.length; i++) {                                      
    document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.lo
                    cations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.location
                    s[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n")
            ;                                                                               
       <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET
                       ' action='/search.php'><input type='text' name='name' placeholder='' value='" + 
                       obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.loca
                       tions[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i
                       ].glon + "'/><span id='geopher'></span><select name='service'><option value='Foo
                       d'>Food</option><option selected value='Search'>Search</option></select><input t
                       ype='submit' value='Search' /><br />"); -->                                     
}                                                                               
</script>                                                                       
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="
59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-
31 12:00:00" paid="50" />                                                       
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http
://berkeley.edu/">                                                              
<p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>                                 
</location>
</body>
</html>

Source: https://www.piperpal.com/location/berkeley/index.html

<html>
  <head>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="utf-8">
    
    <!--[if IE 8]>
  <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
  <![endif]-->
    <!--[if !(IE 8)]><!-->
   <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
   <!--<![endif]-->
   
        <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
      <![endif]-->
   
   <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
   <!--[if IE 7]>
      <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <!--[if IE 6]>
      <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
   <script src="//code.jquery.com/jquery-1.10.2.js"></script>
   <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
   <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
   <link rel="dns-prefetch" href="//maps.googleapis.com">
   <link rel="dns-prefetch" href="//maps.gstatic.com">
   <link rel="dns-prefetch" href="//mts0.googleapis.com">
   <link rel="dns-prefetch" href="//fonts.googleapis.com">
   <link rel="dns-prefetch" href="//www.piperpal.com">
   <title>Location Tags in Berkeley, CA</title>
   <link href="my_style_form.css" type="text/css" rel="stylesheet" />
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
  </head>
  <body>
<h1>Location Tags in Berkeley, CA</h1>
<script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=37.4375596&glon=-122.11922789999998"></script>
<script language="JavaScript">
var obj = JSON.parse(locations);
for (i=0; i < obj.locations.length; i++) {
   document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
   <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
}
</script>
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
<p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
</location>
</body>
</html>

Source: https://www.piperpal.com/location/copenhagen/index.html

<html>
  <head>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="utf-8">
    
    <!--[if IE 8]>
  <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
  <![endif]-->
    <!--[if !(IE 8)]><!-->
   <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
   <!--<![endif]-->
   
        <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
      <![endif]-->
   
   <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
   <!--[if IE 7]>
      <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <!--[if IE 6]>
      <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
   <script src="//code.jquery.com/jquery-1.10.2.js"></script>
   <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
   <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
   <link rel="dns-prefetch" href="//maps.googleapis.com">
   <link rel="dns-prefetch" href="//maps.gstatic.com">
   <link rel="dns-prefetch" href="//mts0.googleapis.com">
   <link rel="dns-prefetch" href="//fonts.googleapis.com">
   <link rel="dns-prefetch" href="//www.piperpal.com">
   <title>Location Tags in Copenhagen, DK</title>
   <link href="my_style_form.css" type="text/css" rel="stylesheet" />
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
  </head>
  <body>
<h1>Location Tags in Copenhagen, DK</h1>
<script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=55.6828273&glon=12.6082921"></script>
<script language="JavaScript">
var obj = JSON.parse(locations);
for (i=0; i < obj.locations.length; i++) {
   document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
   <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
}
</script>
<location name="Copenhagen" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
<p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
</location>
</body>
</html>

Source: https://www.piperpal.com/location/london/index.html

<html>
  <head>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="utf-8">
    
    <!--[if IE 8]>
  <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
  <![endif]-->
    <!--[if !(IE 8)]><!-->
   <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
   <!--<![endif]-->
   
        <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
      <![endif]-->
   
   <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
   <!--[if IE 7]>
      <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <!--[if IE 6]>
      <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
   <script src="//code.jquery.com/jquery-1.10.2.js"></script>
   <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
   <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
   <link rel="dns-prefetch" href="//maps.googleapis.com">
   <link rel="dns-prefetch" href="//maps.gstatic.com">
   <link rel="dns-prefetch" href="//mts0.googleapis.com">
   <link rel="dns-prefetch" href="//fonts.googleapis.com">
   <link rel="dns-prefetch" href="//www.piperpal.com">
   <title>Location Tags in London, United Kingdom</title>
   <link href="my_style_form.css" type="text/css" rel="stylesheet" />
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
  </head>
  <body>
<h1>Location Tags in London, United Kingdom</h1>
<script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=51.5073219&glon=-0.1276474"></script>
<script language="JavaScript">
var obj = JSON.parse(locations);
for (i=0; i < obj.locations.length; i++) {
   document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
   <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
}
</script>
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
<p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
</location>
</body>
</html>

Source: https://www.piperpal.com/location/nyc/index.html

<html>
  <head>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="utf-8">
    
    <!--[if IE 8]>
  <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
  <![endif]-->
    <!--[if !(IE 8)]><!-->
   <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
   <!--<![endif]-->
   
        <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
      <![endif]-->
   
   <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
   <!--[if IE 7]>
      <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <!--[if IE 6]>
      <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
   <script src="//code.jquery.com/jquery-1.10.2.js"></script>
   <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
   <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
   <link rel="dns-prefetch" href="//maps.googleapis.com">
   <link rel="dns-prefetch" href="//maps.gstatic.com">
   <link rel="dns-prefetch" href="//mts0.googleapis.com">
   <link rel="dns-prefetch" href="//fonts.googleapis.com">
   <link rel="dns-prefetch" href="//www.piperpal.com">
   <title>Location Tags in New York City, NY</title>
   <link href="my_style_form.css" type="text/css" rel="stylesheet" />
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
  </head>
  <body>
<h1>Location Tags in New York City, NY</h1>
<script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=40.6399278&glon=-73.7786925"></script>
<script language="JavaScript">
var obj = JSON.parse(locations);
for (i=0; i < obj.locations.length; i++) {
   document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
   <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
}
</script>
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
<p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
</location>
</body>
</html>

Source: https://www.piperpal.com/location/oslo/index.html

<html>
  <head>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="utf-8">
    
    <!--[if IE 8]>
  <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
  <![endif]-->
    <!--[if !(IE 8)]><!-->
   <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
   <!--<![endif]-->
   
        <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
      <![endif]-->
   
   <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
   <!--[if IE 7]>
      <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <!--[if IE 6]>
      <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
   <script src="//code.jquery.com/jquery-1.10.2.js"></script>
   <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
   <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
   <link rel="dns-prefetch" href="//maps.googleapis.com">
   <link rel="dns-prefetch" href="//maps.gstatic.com">
   <link rel="dns-prefetch" href="//mts0.googleapis.com">
   <link rel="dns-prefetch" href="//fonts.googleapis.com">
   <link rel="dns-prefetch" href="//www.piperpal.com">
   <title>Location Tags in Oslo, Norway</title>
   <link href="my_style_form.css" type="text/css" rel="stylesheet" />
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
  </head>
  <body>
<h1>Location Tags in Oslo, Norway</h1>
<script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=60&glon=10"></script>
<script language="JavaScript">
var obj = JSON.parse(locations);
for (i=0; i < obj.locations.length; i++) {
   document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
   <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
}
</script>
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
<p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
</location>
</body>
</html>

Source: https://www.piperpal.com/location/paris/index.html

<html>
  <head>
    <meta property="al:android:app_name" content="Piperpal" />
    <meta property="al:android:package" content="com.piperpal.api.android" />
    <meta property="al:android:url" content="https://www.piperpal.com/Android" />
    <!--[if IE]><![endif]-->
    <meta charset="utf-8">
    
    <!--[if IE 8]>
  <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
  <![endif]-->
    <!--[if !(IE 8)]><!-->
   <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
   <!--<![endif]-->
   
        <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
      <![endif]-->
   
   <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
   <!--[if IE 7]>
      <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <!--[if IE 6]>
      <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
   <script src="//code.jquery.com/jquery-1.10.2.js"></script>
   <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
   <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
   <link rel="dns-prefetch" href="//maps.googleapis.com">
   <link rel="dns-prefetch" href="//maps.gstatic.com">
   <link rel="dns-prefetch" href="//mts0.googleapis.com">
   <link rel="dns-prefetch" href="//fonts.googleapis.com">
   <link rel="dns-prefetch" href="//www.piperpal.com">
   <title>Location Tags in Paris, France</title>
   <link href="my_style_form.css" type="text/css" rel="stylesheet" />
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
  </head>
  <body>
<h1>Location Tags in Paris, France</h1>
<script type="text/javascript" src="https://api.piperpal.com/location/json.php?service=Books&glat=48.8566969&glon=2.3514616"></script>
<script language="JavaScript">
var obj = JSON.parse(locations);
for (i=0; i < obj.locations.length; i++) {
   document.write("<h1>" + obj.locations[i].name + "</h1><h2><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a> (" + obj.locations[i].distance + ")</h2><h3>" + " " + obj.locations[i].service + " " + "</h3>\n");
   <!--document.write("<p>" + obj.locations[i].distance + "</p><form method='GET' action='/search.php'><input type='text' name='name' placeholder='' value='" + obj.locations[i].name + "'/><input type='hidden' name='glat' value='" + obj.locations[i].glat + "' /><input type='hidden' name='glon' value='" + obj.locations[i].glon + "'/><span id='geopher'></span><select name='service'><option value='Food'>Food</option><option selected value='Search'>Search</option></select><input type='submit' value='Search' /><br />"); -->
}
</script>
<location name="Berkeley" location="http://berkeley.edu/" service="Books" glat="59.9340451" glon="10.7481188" notbefore="2020-03-30 12:00:00" notafter="2020-03-31 12:00:00" paid="50" />
<location name="Palo Alto" lat="37.4375596" lon="-122.11922789999998" href="http://berkeley.edu/">
<p>Check out <a href="https://www.geopher.com/">Geopher</a> and <a href="http://piperpal.com/">Piperpal</a>.</p>
</location>
</body>
</html>

Location API on World Wide Web - api.piperpal.com/location

Source: https://api.piperpal.com/location/json.php

<?php
$db = mysqli_connect("piperpal.mysql.domeneshop.no","piperpal","xxxxxxxx","piperpal");
// mysqli_set_charset($db,"utf8");
if (isset($_GET['name'])) {
  $query = "SELECT DISTINCT id,name,service,location,modified,created,glat,glon,paid,token,type,email,111.045*DEGREES(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat)))) AS distance_in_km FROM piperpal JOIN (SELECT  " . $_GET['glat'] . "  AS latpoint, " . $_GET['glon'] . " AS longpoint) AS p ON 1=1 WHERE service = '" . $_GET['service'] . "' AND name = '" . $_GET['name'] . "' ORDER BY distance_in_km;";
} else {
    if (isset($_GET['service'])) {
        $query = "SELECT DISTINCT id,name,service,location,modified,created,glat,glon,paid,token,type,email,111.045*DEGREES(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat)))) AS distance_in_km FROM piperpal JOIN (SELECT  " . $_GET['glat'] . "  AS latpoint, " . $_GET['glon'] . " AS longpoint) AS p ON 1=1 WHERE service = '" . $_GET['service'] . "' ORDER BY distance_in_km";
    } else {
        $query = "SELECT DISTINCT id,name,service,location,modified,created,glat,glon,paid,token,type,email,111.045*DEGREES(ACOS(COS(RADIANS(latpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RADIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat)))) AS distance_in_km FROM piperpal JOIN (SELECT  " . $_GET['glat'] . "  AS latpoint, " . $_GET['glon'] . " AS longpoint) AS p ON 1=1 ORDER BY distance_in_km";    
    }
}
$result = $db->query($query);
// print $query;
$num_coords = mysqli_num_rows($result);
if ($num_coords == 0) {
  print '<h3>' . $_GET['service'] . '</h3><ul><li><a href="http://piperpal.com/cft/?location=' . $_GET['service'] . '&service=' . basename($_SERVER['HTTP_REFERER']) . '">New</a></li><li>Upvote</li><li>Comment</li><li>Stamp</li></ul></ul>';
//  header("Location: http://piperpal.com/");
} else {
  // print "$(function(){\n  var locations = [\n";
  print "var locations = '{ \"locations\" : [' + '";
  $count = 0;
  //  print "<h1>" . $_GET['service'] . "</h1>";
  while($object = mysqli_fetch_object($result)) {
    $count++;
    if ($count == $num_coords) {
      print '{"id": "' . $object->id . '", "name": "' . $object->name . '", "service": "' . $object->service . '", "location": "' . $object->location . '", "modified": "' . $object->modified . '", "created": "' . $object->created . '", "glat": "' . $object->glat . '", "glon": "' . $object->glon . '", "paid": "' . $object->paid . '", "token": "' . $object->token . '", "type": "' . $object->type . '", "distance": "' . $object->distance_in_km . '", "email": "' . $object->email . '"}';
    } else {
      print '{"id": "' . $object->id . '", "name": "' . $object->name . '", "service": "' . $object->service . '", "location": "' . $object->location . '", "modified": "' . $object->modified . '", "created": "' . $object->created . '", "glat": "' . $object->glat . '", "glon": "' . $object->glon . '", "paid": "' . $object->paid . '", "token": "' . $object->token . '", "type": "' . $object->type . '", "distance": "' . $object->distance_in_km . '", "email": "' . $object->email . '"},';
    }
  }
  print "]}';\n";
}
?>

Source: https://api.piperpal.com/location/pull.php

<?php

$fp = fopen("/home/4/p/piperpal/data.csv", "a+");
fwrite($fp, "pull" . ";" . $_SERVER['REMOTE_ADDR'] . ";" . $_GET['name'] . "\n");
fclose($fp);

header("Location: https://piperpal.com/cft/s/?name=" . $_GET['name'] . "&glat=" . $_GET['glat'] . "&location=" . $_GET['location'] . "&glon=" . $_GET['glon'] . "&service=" . $_GET['service'] . "&paid=" . $_GET['paid']);

exit(0);

/* $db = mysqli_connect("piperpal.mysql.domeneshop.no","piperpal","FiFLHHPxyR7PXUg","piperpal"); */

/* $query = "INSERT INTO piperpal (name,location,service,glat,glon) VALUES ('" . $_GET['name'] . "', '" . $_GET['location'] . "', '" . $_GET['service'] . "', " . $_GET['glat'] . "," . $_GET['glon'] . ");"; */

/* $result = $db->query($query); */
?>

Source: https://api.piperpal.com/location/robot.php

<?php

$fp = fopen("/home/4/p/piperpal/data.csv", "a+");
fwrite($fp, "push;" . $_SERVER['REMOTE_ADDR'] . ";" . $_GET['name'] . "\n");
fclose($fp);
#header("Location: https://piperpal.com/cft/s/?name=" . $_GET['name'] . "&glat=" . $_GET['glat'] . "&location=" . $_GET['location'] . "&glon=" . $_GET['glon'] . "&service=" . $_GET['service'] . "&paid=" . $_GET['paid']);

#exit(0);

# echo $_SERVER['REMOTE_ADDR'];

# if ($_SERVER['REMOTE_ADDR']=="178.255.144.178" || $_SERVER['REMOTE_ADDR']=="51.175.144.124") {
if ($_SERVER['REMOTE_ADDR']=="178.255.144.178") {
    $db = mysqli_connect("piperpal.mysql.domeneshop.no","piperpal","xxxxxxxx","piperpal");
    $query = "INSERT INTO piperpal (name,location,service,glat,glon,paid) VALUES ('" . $_GET['name'] . "', '" . $_GET['location'] . "', '" . $_GET['service'] . "', " . $_GET['glat'] . "," . $_GET['glon'] . "," . $_GET['paid'] . ") WHERE NOT EXISTS (SELECT name FROM piperpal WHERE name = '" . $_GET['name'] . "');";
    // print $query . "\n";
    $result = $db->query($query);
}
?>

Source: https://api.piperpal.com/location/push.php

<?php

// require_once('/home/4/p/piperpal/stripe-php/init.php');
// require_once('/home/4/p/piperpal/YayLocation.php');

// $yay = new YayLocation($_POST);

$token = $_POST['stripeToken'];

//      print "INSERT IGNORE INTO piperpal (name, location, service, glat, glon, modified, created, paid, token, type, email) VALUES ('" . $_POST['name'] . "','" . $_POST['location'] . "','" . $_POST['service'] . "','" . $_POST['glat'] . "','" . $_POST['glon'] . "','" . date("Y-m-d h:i:s",strtotime($_POST['notBefore'])) . "','" . date("Y-m-d h:i:s",strtotime($_POST['notAfter'])) . "', '" . $_POST['paid'] . "','" . $_POST['stripeToken'] . "', '" . $_POST['stripeTokenType'] . "','" . $_POST['stripeEmail'] . "') ON DUPLICATE KEY UPDATE modified = NOW();";

// try {
    
//     if ($yay->get_freedate($_POST['notBefore'], $_POST['notAfter']) == TRUE) {
        
//         $yay->get_checkout("INSERT IGNORE INTO piperpal (name, location, service, glat, glon, modified, created, paid, token, type, email) VALUES ('" . $_POST['name'] . "','" . $_POST['location'] . "','" . $_POST['service'] . "','" . $_POST['glat'] . "','" . $_POST['glon'] . "', '" . date("Y-m-d h:i:s",strtotime($_POST['notBefore'])) . "','" . date("Y-m-d h:i:s",strtotime($_POST['notAfter'])) . "','" . $_POST['paid'] . "','" . $_POST['stripeToken'] . "', '" . $_POST['stripeTokenType'] . "','" . $_POST['stripeEmail'] . "') ON DUPLICATE KEY UPDATE modified = NOW();");
//         print_r($yay->result);
        
//         $stripe = array(
//             "secret_key"      => "sk_live_51MsrtFAgJ7jHvJPRhemuILSINCR\
M9BNoTPwV9GCNbq8oWmq7xm5SWsGecQUL2xCaC\
mhjnorBFlbyuSIaDU1hjrP300YpX28hR2",
//             "publishable_key" => "pk_live_51MsrtFAgJ7jHvJPRzksQbNY4573\
e98c9MPwsnOXymtKYWFUVgh6BbmZV9tPhhTwpp\
FLDabbfm7Lkj9dEYaJBD9em00xNBVHJzf"
//         );
        
//         \Stripe\Stripe::setApiKey($stripe['secret_key']);
        
//         if ($_POST['paid'] > 0) {
            
//             $charge = \Stripe\Charge::create(array("amount" => $_POST['paid'],
//                                                    "currency" => "usd",
//                                                    "source" => $token,
//                                                    /                                  "description" => $_POST['name']));
//         }
//     }
// }
// catch(\Stripe\Error\Card $e) {
//   print "The card has been declined.  Please try another card.";
// }

if ($_POST['paid'] > 0) {
    $fp = fopen("/home/4/p/piperpal/data.csv", "a+");
    fwrite($fp, "push;" . time() . ";" . $_SERVER['REMOTE_ADDR'] . ";" . $_POST['name'] . ";" . $token . "\n");
    fclose($fp);
    $db = mysqli_connect("piperpal.mysql.domeneshop.no","piperpal","xxxxxxxx","piperpal");
    $query = "INSERT IGNORE INTO piperpal (name, location, service, glat, glon, modified, created, paid, token, type, email) VALUES ('" . $_POST['name'] . "','" . $_POST['location'] . "','" . $_POST['service'] . "','" . $_POST['glat'] . "','" . $_POST['glon'] . "', '" . date("Y-m-d h:i:s",strtotime($_POST['notBefore'])) . "','" . date("Y-m-d h:i:s",strtotime($_POST['notAfter'])) . "','" . $_POST['paid'] . "','" . $_POST['stripeToken'] . "', '" . $_POST['stripeTokenType'] . "','" . $_POST['stripeEmail'] . "') ON DUPLICATE KEY UPDATE modified = NOW();";
    $result = $db->query($query);
    header("Location: https://www.piperpal.com/?name=" . $_POST['name'] . "&glat=" . $_POST['glat'] . "&location=" . $_POST['location'] . "&glon=" . $_POST['glon'] . "&service=" . $_POST['service'] . "&paid=" . $_POST['paid']);

    print "<!DOCTYPE html><html lang='en'><head><meta charset='utf-8' />";
    print "<meta http-equiv='refresh' content='120; url=https://www.piperpal.com/?query=" . $_POST['name'] . "&radius=10000&search=Go&glat=" . $_POST['glat'] . "&glon=" . $_POST['glon'] . "'>";
    
    print "</head>\n";
    print "<body>\n";
    print "<h1>piperpal.com</h1>\n";
    print "&lt;location name=\"" . $_POST['name'] . "\" location=\"" . $_POST['location'] . "\" service=\"" . $_POST['service'] . "\" glat=\"" . $_POST['glat'] . "\" glon=\"" . $_POST['glon'] . "\" notbefore=\"" . date("Y-m-d h:i:s",strtotime($_POST['notBefore'])) . "\" notafter=\"" . date("Y-m-d h:i:s",strtotime($_POST['notAfter'])) . "\" paid=\"" . $_POST['paid'] . "\" /&gt;";        
    //    print "<p>We will process the payment...</p>\n";
    print "<p>Redirecting to the Location search engine.</p>\n";
}

exit(0);

?>

Resolver Interface on World Wide Web - api.piperpal.com/resolver/

Source: https://api.piperpal.com/resolver/index.php

<?php

$fp = fopen("/home/4/p/piperpal/rank.csv", "a+");
fwrite($fp, "rank:" . $_SERVER['REMOTE_ADDR'] . ";" . $_GET['name'] . ";" . $_GET['location'] . ";" . $_GET['service'] . ";" . $_GET['paid'] . "\n");
fclose($fp);
#header("Location: https://piperpal.com/cft/s/?name=" . $_GET['name'] . "&glat=" . $_GET['glat'] . "&location=" . $_GET['location'] . "&glon=" . $_GET['glon'] . "&service=" . $_GET['service'] . "&paid=" . $_GET['paid']);
#https://api.piperpal.com/resolver/?name=Wikipedia+%28Encyclop%C3%A6dia%29&service=Books&location=http://www.wikipedia.org/&glat=59.93405070&glon=10.74806250&paid=1
#exit(0);

# echo $_SERVER['REMOTE_ADDR'];

# if ($_SERVER['REMOTE_ADDR']=="178.255.144.178" || $_SERVER['REMOTE_ADDR']=="51.175.144.124") {
if ($_SERVER['REMOTE_ADDR']=="178.255.144.178") {
    $db = mysqli_connect("piperpal.mysql.domeneshop.no","piperpal","xxxxxxxx","piperpal");
    $query = "INSERT INTO piperpal (name,location,service,glat,glon,paid) VALUES ('" . $_GET['name'] . "', '" . $_GET['location'] . "', '" . $_GET['service'] . "', " . $_GET['glat'] . "," . $_GET['glon'] . "," . $_GET['paid'] . ") WHERE NOT EXISTS (SELECT name FROM piperpal WHERE name = '" . $_GET['name'] . "');";
    // print $query . "\n";
    $result = $db->query($query);
}
?>

Market Interface - www.piperpal.com/market/

Source: https://www.piperpal.com/market/index.cgi

#!/usr/bin/perl

# Copyright (C) 2018  Ole Aamot Software
#
# Author: ole@aamotsoftware.com
#
# Date: 2018-04-06T06:40:00+01
#
# Field: Incremental, location, sql, perl
#
# URL: https://www.piperpal.com/market/index.cgi

use strict;
use warnings;
use DBI;
use CGI qw/:standard/;
use CGI::Cookie;
use lib '../..';
use Piperpal;

my $c = CGI->new;
print "Content-Type: text/html\n\n";
print <<EOF;
<!DOCTYPE html>
<html lang="en">
    <head>

    <!--[if IE]><![endif]-->
    <meta charset="utf-8">

    <!--[if IE 8]>
      <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->
   <!--[if !(IE 8)]><!-->
      <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
    <!--<![endif]-->

    <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->

    <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
  <!--[if IE 7]>
    <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
  <!--[if IE 6]>
    <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

    <link rel="dns-prefetch" href="//maps.googleapis.com">
    <link rel="dns-prefetch" href="//maps.gstatic.com">
    <link rel="dns-prefetch" href="//mts0.googleapis.com">
    <link rel="dns-prefetch" href="//fonts.googleapis.com">
    <link rel="dns-prefetch" href="//www.piperpal.com">
    <title>piperpal.com - Location-based Search Engine</title>
    <link href="my_style_form.css" type="text/css" rel="stylesheet" />
    <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
    <meta charset="utf-8" />
    <script>
    function price_changed() {
        var priceWidget = document.getElementById('price');
        var price = priceWidget.options[priceWidget.selectedIndex].value;
        var stripeSubmit = document.getElementsByClassName('stripe-button-el')[0];
        var regularSubmit = document.getElementById('regular-submit');
        if (price > 0) {
            stripeSubmit.style.display = 'inline-block';
            regularSubmit.style.display = 'none';
        } else {
            stripeSubmit.style.display = 'none';
            regularSubmit.style.display = 'inline-block';
        }
}

function updateGeo() {
    var glat = document.getElementById("glat");
    var glon = document.getElementById("glon");
    
    glat.value = position.coords.latitude;
    glon.value = position.coords.longitude;

    alert(glat+","+glon);
}

function getWikipedia() {
    jQuery(function($) {
        $.getJSON('http://api.geonames.org/findNearbyWikipediaJSON?formatted=true&lat='+ position.coords.latitude +'&lng='+ position.coords.longitude +'&username=username&style=full&lang=en&wikipediaUrl&thumbnailImg', function(json){

            for(var i = 0; i < json.geonames.length; i++)
            {
                $("#wikipedia").prepend('<span style="font-family: geneva, arial, helvetica, sans-serif;"><br><br><img src="wikilogo.gif"><br>' + json.geonames[i].summary + '<br><a href="http://'+ json.geonames[i].wikipediaUrl +'" target="_blank">'+ json.geonames[i].wikipediaUrl +'</a><br></span>');
                  }
            }); });
}

function submit() {
        // Strip hijacks the form submit, so we need to un-hijack it.
            var form = document.getElementById('form');
        form.submit();
}
    </script>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
    <meta http-equiv="X-UA-Compatible" content="IE=edge" >
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>

    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

    <script type="text/javascript" src="https://www.piperpal.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="https://www.piperpal.com/jquery.autocomplete.min.js"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-names.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-services.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-locations.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-queries.php"></script>
    <meta name="viewport" content="width=620" />
    <script>
    \$(function() {
        \$( "#datepicker" \)\.datepicker\(\)\;
        \$( "#simple-search-tourout" \)\.datepicker\(\)\;
    \}\)\;
    </script>
    </head>
    <body style="background: #ffffff;" onload="document.getElementById('query').focus();">
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <!--script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"--><!--/script-->
    <script>
        function success(position) {
        var s = document.querySelector('#status');
        
        if (s.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        s.innerHTML = '<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
        s.className = 'success';

        var q = document.querySelector('#status_publisher');
        
        if (q.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        q.innerHTML = '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

        // '<input type=text name=glat size=16 value=' + position.coords.latitude + ' /><input type=text name=glon size=16 value=' + position.coords.longitude + ' />';
        q.className = 'success';

        var r = document.querySelector('#status_lns');
        
        if (r.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        r.innerHTML =  '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

//'<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
        r.className = 'success';

        var mapcanvas = document.createElement('div');
        mapcanvas.id = 'mapcanvas';
        mapcanvas.style.height = '400px';
        mapcanvas.style.width = '640px';
        
        document.querySelector('article').appendChild(mapcanvas);
        
        var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
        var myOptions = {
        zoom: 15,
        center: latlng,
        mapTypeControl: false,
        navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
        mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
        
        var marker = new google.maps.Marker({
                position: latlng, 
                                map: map, 
                                title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
                                });

        var locations = [
         ['Banja Luka', 44.766666699999990000, 17.183333299999960000, 4],
    ['Tuzla', 44.532841000000000000, 18.670499999999947000, 5],
    ['Zenica', 44.203439200000000000, 17.907743200000027000, 3],
    ['Sarajevo', 43.850000000000000000, 18.250000000000000000, 2],
    ['Mostar', 43.333333300000000000, 17.799999999999954000, 1]
];

var infowindow = new google.maps.InfoWindow();

var marker, i;
for (i = 0; i < locations.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][1], locations[i][2]),
      map: map
                                    });

google.maps.event.addListener(marker, 'click', (function (marker, i) {
    return function () {
        infowindow.setContent(locations[i][0]);
        infowindow.open(map, marker);
    }
                                                })(marker, i));
}
}

function error(msg) {
        // var s = document.querySelector('#status');
        // s.innerHTML = typeof msg == 'string' ? msg : "failed";
        // s.className = 'fail';
        
        // console.log(arguments);
}

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(success, error);
} else {
        error('not supported');
}

</script>

    <center><table><tr><td valign='top' width=600><a href="https://www.piperpal.com/"><img src='/piperpal.png' alt='piperpal.com Logo' width=600/></a></td></tr></table>
    
    <div class="background_form">
EOF

print "<table>";
print "<tr><td valign='top' width=600>";
print "<center><h3>Discover the world around you</h3></center>";
print "</td></tr></table>";
&Piperpal::select_location();
print "<br />";
print "<p>Hint: You could markup with &lt;location&gt; tag in <a href='https://www.w3.org/wiki/HTML/next#.3Clocation.3E_element_.28like_.29_for_expressing_geo_information.2C_eg_with_attributes_lat.2C_long.2C_altitude'>HTML.next</a><br />";
print "Proposal: <a href=\"https://www.aamotsoftware.com/location.html\">https://www.aamotsoftware.com/location.html</a><br />";
print "JSON in HTML5: <a href=\"https://www.piperpal.com/google.html\">https://www.piperpal.com/google.html</a></p>";
print "<p><a href=\'https://www.stripe.com/\'><img alt=\'Powered by stripe\' src=\'/powered_by_stripe.png\'></a>&nbsp;<a href=\'https://play.google.com/store/apps/details?id=com.piperpal.api.android&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play\' src=\'/google-piperpal.png\'/></a></p>";
print "<p>Copyright &copy; 2015-2020  <location name='Aamot Software' href='https://www.aamotsoftware.com/' lat='37.4219999' lon='-122.0862462' service='Electronics'>Aamot Software</location><br /><location name='Piperpal' href='https://www.piperpal.com/' lat='59.94215220' lon='10.71697530' service='Crawler'>Oslo, Norway</location> - <location name='Piperpal' href='https://www.piperpal.com/' lat='37.879015' lon='-122.262425' service='Crawler'>Berkeley, California, USA</location></p>";
print "</td></tr></table>\n";
print "</body>\n</html>\n";

Buying Interface - www.piperpal.com/google.html

Source: https://www.piperpal.com/google.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
    <!--[if IE 8]>
    <link href="/css/common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->
    <!--[if !(IE 8)]><!-->
   <link href="/css/common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
   <!--<![endif]-->
   
        <!--[if lt IE 9]>
      <link href="/css/airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
      <![endif]-->
   
   <link href="/css/main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
   <!--[if IE 7]>
      <link href="/css/p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <!--[if IE 6]>
      <link href="/css/p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
      <![endif]-->
   <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
   <link rel="dns-prefetch" href="//maps.googleapis.com">
   <link rel="dns-prefetch" href="//maps.gstatic.com">
   <link rel="dns-prefetch" href="//mts0.googleapis.com">
   <link rel="dns-prefetch" href="//fonts.googleapis.com">
   <link rel="dns-prefetch" href="//www.piperpal.com">
   <title>piperpal.com - Location-based Search Engine</title>
   <link href="my_style_form.css" type="text/css" rel="stylesheet" />
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web:700' rel='stylesheet' type='text/css'>
   <link href='http://fonts.googleapis.com/css?family=Titillium+Web' rel='stylesheet' type='text/css'>
   <script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
  </head>
  <!-- Styles -->
  <style>
    #name label{
    display: inline-block;
    width: 100px;
    text-align: right;
    }
    #name_submit{
    padding-left: 100px;
    }
    #name div{
    margin-top: 1em;
    }
    textarea{
    vertical-align: top;
    height: 5em;
    }

    .error{
    display: none;
    margin-left: 10px;
    }

    .error_show{
    color: red;
    margin-left: 10px;
    }

    input.invalid, textarea.invalid{
    border: 2px solid red;
    }

    input.valid, textarea.valid{
    border: 2px solid green;
    }
    input {
    padding: 10px;
    font: 20px Arial;
    width: 70%;
    }
    </style>
  <body>
    <!-- JavaScript Code -->
    <script>
      var currencyInput = document.querySelector('input[type="currency"]')
      var currency = 'USD' // https://www.currency-iso.org/dam/downloads/lists/list_one.xml
      
      // format inital value
      onBlur({target:currencyInput})
      
      // bind event listeners
      currencyInput.addEventListener('focus', onFocus)
      currencyInput.addEventListener('blur', onBlur)
      
      
      function localStringToNumber( s ){
     return Number(String(s).replace(/[^0-9.-]+/g,""))
      }
      
      function onFocus(e){
     var value = e.target.value;
     e.target.value = value ? localStringToNumber(value) : ''
      }
      
      function onBlur(e){
   var value = e.target.value
   
   var options = {
       maximumFractionDigits : 2,
       currency              : currency,
       style                 : "currency",
       currencyDisplay       : "symbol"
   }
   
   e.target.value = (value || value === 0) 
       ? localStringToNumber(value).toLocaleString(undefined, options)
       : ''
      }
      
      $(document).ready(function() {
      <!-- Real-time Validation -->
      <!--Name can't be blank-->
      $('#name').on('input', function() {
      var input=$(this);
      var is_name=input.val();
      if(is_name){input.removeClass("invalid").addClass("valid");}
      else{input.removeClass("valid").addClass("invalid");}
      });

      <!--Email must be an email -->
      $('#email').on('input', function() {
      var input=$(this);
      var re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
      var is_email=re.test(input.val());
      if(is_email){input.removeClass("invalid").addClass("valid");}
      else{input.removeClass("valid").addClass("invalid");}
      });

      <!--Website must be a website -->
      $('#location').on('input', function() {
      var input=$(this);
      if (input.val().substring(0,4)=='www.'){input.val('http://www.'+input.val().substring(4));}
      var re = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?/;
      var is_url=re.test(input.val());
      if(is_url){input.removeClass("invalid").addClass("valid");}
      else{input.removeClass("valid").addClass("invalid");}
      });

      <!--Message can't be blank -->
      $('#service').keyup(function(event) {
      var input=$(this);
      var message=$(this).val();
      console.log(message);
      if(message){input.removeClass("invalid").addClass("valid");}
      else{input.removeClass("valid").addClass("invalid");}
      });

      <!-- After Form Submitted Validation-->
      $("#submit button").click(function(event){
      var form_data=$("#name").serializeArray();
      var error_free=true;
      for (var input in form_data){
      var element=$("#name_"+form_data[input]['name']);
      var valid=element.hasClass("valid");
      var error_element=$("span", element.parent());
      if (!valid){error_element.removeClass("error").addClass("error_show"); error_free=false;}
      else{error_element.removeClass("error_show").addClass("error");}
      }
      if (!error_free){
      event.preventDefault();
      }
      else{
      alert('No errors: Form will be submitted');
      }
      });
      });
    </script>
    <h1><a href="https://www.piperpal.com/">Piperpal</a></h1>
    <form id="form" method="GET" action="https://api.piperpal.com/location/push.php">
      <table>
 <tr>
   <td>Text: <input id="name" type="text" name="name" placeholder="Example: FriendliestCoffeeShop" size="24" /><span class="error">This field is required</span></td>
 </tr>
 <tr>
   <td>Email: <input id="email" type="text" name="email" placeholder="your.name@gmail.com" /><span class="error">This field is required</span></td>
 </tr>
 <tr>
   <td>Service: <select id="service" name="service"><option value="Restaurant">Restaurant</option><option value="Bar">Bar</option><option value="Concert">Concert</option><option value="Film">Film</option><option value="Books">Books</option><option value="Health">Health</option><option value="Clothes">Clothes</option><option value="Food">Food</option><option value="Music">Music</option><option value="Electronics">Electronics</option><option value="Transport">Transport</option><option value="Rental">Rental</option></select></td>
 </tr>
 <tr>
   <td>Location: <input type="text" name="location" placeholder="https://yourwebsite.com/" /></td>
 </tr>
 <!--
        <tr>
          <td>Latitude: <input type="text" name="glat" value="37.4375596"></td>
        </tr>
        <tr>
          <td>Longitude: <input type="text" name="glon" value="-122.11922789999998"></td>                                                                             </tr>
        -->
 <tr>
   <td>Payment (¢): <input type="currency" name="paid" value="42" placeholder="Type a price"></td>
 </tr>
 <tr>
   <td><input type="submit" name="Submit" value="Submit" /></td>
 </tr>
      </table>
    </form>
    <h2>Piperpal / Were / Here / After</h2>
    <p>Peter Norvig came up with <a href="https://api.piperpal.com/location/push.php?name=FriendliestCoffeeShop&service=Search&location=https://research.google.com/&glat=37.4375596&glon=-122.11922789999998&paid=43">&amp;FriendliestCoffeeShop</a> at <a href="https://api.piperpal.com/location/push.php?name=GoogleVisitorCenter&service=Search&location=https://www.google.com/&glat=37.4375596&glon=-122.11922789999998&paid=42">&amp;GoogleVisitorCenter</a>:<a href="https://piperpal.com/service/0/service.php">%Search</a> in Palo Alto, California in 2015.</p>
    <p>Ole thought that the <a href="https://api.piperpal.com/location/push.php?name=FriendliestCoffeeShop&service=Search&location=https://www.kaffebrenneriet.no/butikkene/l%C3%B8renveien-43-l%C3%B8ren&glat=59.930553&glon=10.7919344&paid=42">&amp;FriendliestCoffeeShop</a> is at <a href="https://api.piperpal.com/location/push.php?name=Kaffebrenneriet&service=Search&location=https://www.kaffebrenneriet.no/butikkene/l%C3%B8renveien-43-l%C3%B8ren&glat=59.930553&glon=10.7919344&paid=42">&amp;Kaffebrenneriet</a>:<a href="https://piperpal.com/service/8/service.php">%Food</a> in Oslo, Norway in 2019.</p>
    <p>Moddi played a solo concert at the <a href="https://api.piperpal.com/location/push.php?name=CoziestVinylShop&service=Music&location=http://www.bigdipper.no/&glat=59.9137584&glon=10.7433188&paid=42">&CoziestVinylShop</a> and signed his brand new record on our request at <a href="https://api.piperpal.com/location/push.php?name=BigDipper&service=Music&location=http://www.bigdipper.no/&glat=59.9137584&glon=10.7433188&paid=42">&PlatebutikkenBigDipper</a>:<a href="https://piperpal.com/service/9/service.php">%Music</a> on September 11, 2019.
    <p>We thought that the <a href="https://api.piperpal.com/location/push.php?name=ClassyItalianRestaurant&service=Restaurant&glat=59.9181062glon=10.7405857&location=http://www.tekehtopa.no/&paid=42">&amp;ClassyItalianRestaurant</a> is <a href="https://api.piperpal.com/location/push.php?name=Tekehtopa&service=Restaurant&glat=59.9181062glon=10.7405857&location=http://www.tekehtopa.no/&paid=42">&amp;Tekehtopa</a>:<a href="https://piperpal.com/service/1/service.php">%Restaurant</a> in Oslo, Norway on September 11, 2019.</p>
    <p>We ate at <a href="https://api.piperpal.com/location/push.php?name=TheBestLunchPlace&service=Restaurant&location=http://www.cafediroma.no/&glat=59.9224999&glon=10.7549504&paid=42">&amp;TheBestLunchPlace</a> on July 4th, 2020 which we thought was as good as <a href="https://api.piperpal.com/location/push.php?name=CafediRoma&service=Restaurant&location=http://www.cafediroma.no/&glat=59.9224999&glon=10.7549504&paid=42">&CafediRoma</a>:<a href="https://piperpal.com/service/1/service.php">%Restaurant</a> in Sofienberggata 6, Oslo at 12:00.</p>
    <p>We got similar <a href="https://api.piperpal.com/location/push.php?name=WarmNordicJackets&service=Clothes&location=http://www.stormberg.com/&glat=59.9292125&glon=10.7898633&paid=42">&WarmNordicJackets</a> from <a href="https://api.piperpal.com/location/push.php?name=StormbergOslo&service=Clothes&location=http://www.stormberg.com/&glat=59.9292125&glon=10.7898633&paid=42">&amp;StormbergOslo</a>:<a href="https://piperpal.com/service/7/service.php">%Clothes</a> which we thought was better than <a href="https://api.piperpal.com/location/push.php?name=HellyHansen&service=Clothes&location=http://www.hellyhansen.com/&paid=42">&HellyHansen</a>:<a href="https://piperpal.com/service/7/service.php">%Clothes</a> for shorter tours in <a href="https://piperpal.com/Frognerparken">&Frognerparken</a>:<a href="https://piperpal.com/service/4/service.php">%Film</a> at 20:00 on January, 4th 2022.</p>
    <script type="text/javascript" src="https://api.piperpal.com/location/?service=Search">
    </script>
    <script
       src="https://code.jquery.com/jquery-3.3.1.js"
       integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
       crossorigin="anonymous">
      var newLink = "https://api.piperpal.com/location/?service=Search";
      $('script').each(function() {
      var link = $(this).attr('src');
      })
    </script>
    <script language="JavaScript">
      var obj = JSON.parse(locations);
      for (i=0; i < obj.locations.length; i++) {
             document.write("<p><h2><a href='https://piperpal.com/" + obj.locations[i].name + "'>" + obj.locations[i].name + "</a></h2><p>" + obj.locations[i].distance + " km away</p><p><b><a href='" + obj.locations[i].location + "'>" + obj.locations[i].location + "</a></b></p><p><i>" + obj.locations[i].service + " " + "</i></p>\n");
      }
             </script>
</td>
</tr>
</table>
  </body>
</html>

Source: https://www.piperpal.com/cft/index.php

<html>
  <head>
    <title>Piperpal</title>
    <!--[if IE]><![endif]-->
    <meta charset="iso-8859-1">
    <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
    <!--[if IE 8]>
      <link href="common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->
   <!--[if !(IE 8)]><!-->
      <link href="common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
    <!--<![endif]-->
    <!--[if lt IE 9]>
      <link href="airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->
    <link href="main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
  <!--[if IE 7]>
    <link href="p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
  <!--[if IE 6]>
    <link href="p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
  <!-- FIXME
  <script type="text/javascript" src="http://www.piperpal.com/piperpal-autocomplete-tours.php"></script>
  -->
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  <link rel="stylesheet" href="/resources/demos/style.css">
  <script>
   $(function() {
       $( "#simple-search-tourin" ).datepicker();
       $( "#simple-search-tourout" ).datepicker();
     });
  </script>
  </head>
  <body>
    <img src="http://www.piperpal.com/Logo.png" />
    <form id="searchbar-form" action="s">
    <label for="simple-search-location" class="screen-reader-only">
      What do you describe?
    </label>
    <input type="text"
           placeholder="Location Tag?"
           autocomplete="on"
           name="location"
           id="simple-search-location"
           class="input-large js-search-location"
           value="<?php echo $_GET['location']; ?>">
    <label for="simple-search-location" class="screen-reader-only">
      What do you provide?
    </label>
    <input type="text"
           placeholder="Location Service?"
           autocomplete="on"
           name="service"
           id="simple-search-service"
           class="input-large js-search-service"
           value="<?php echo $_GET['service']; ?>">
    <div class="row row-condensed space-top-2 space-2">
      <div class="col-sm-6">
        <label for="simple-search-tourin" class="screen-reader-only">
          Tour in
        </label>
        <input
          id="simple-search-tourin"
          type="text"
          name="notBefore"
          class="input-large tourin js-search-tourin"
          placeholder="Not Before">
      </div>
      <div class="col-sm-6">
        <label for="simple-search-tourout" class="screen-reader-only">
          Tour out
          </label>
        <input
          id="simple-search-tourout"
          type="text"
          name="notAfter"
          class="input-large tourout js-search-tourout"
          placeholder="Not After">
      </div>
    </div>

    <div class="select select-block space-2">
      <label for="simple-search-price" class="screen-reader-only">
        Price
      </label>
      <select id="simple-search-price" name="paid" class="js-search-price">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
        <option value="7">7</option>
        <option value="8">8</option>
        <option value="9">9</option>
        <option value="10">10</option>
      </select>
    </div>
    <button type="submit" class="btn btn-primary btn-large btn-block">
      Search
    </button>
    </form>
  </body>
</html>

Source: https://www.piperpal.com/cft/s/index.php

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
    <title>piperpal.com - Location-based Search Engine</title>
    <!--[if IE]><![endif]-->      
    <!--[if IE 8]>
      <link href="../common_o2.1_ie8-91981ea8f3932c01fab677a25d869e49.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->
   <!--[if !(IE 8)]><!-->
      <link href="../common_o2.1-858f47868a8d0e12dfa7eb60fa84fb17.css" media="all" rel="stylesheet" type="text/css" />
    <!--<![endif]-->

    <!--[if lt IE 9]>
      <link href="../airglyphs-ie8-9f053f042e0a4f621cbc0cd75a0a520c.css" media="all" rel="stylesheet" type="text/css" />
    <![endif]-->

    <link href="../main-f3fcc4027aaa2c83f08a1d51ae189e3b.css" media="screen" rel="stylesheet" type="text/css" />
  <!--[if IE 7]>
    <link href="../p1_ie_7-0ab7be89d3999d751ac0e89c44a0ab50.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
  <!--[if IE 6]>
    <link href="../p1_ie_6-7d6a1fd8fe9fdf1ce357f6b864c83979.css" media="screen" rel="stylesheet" type="text/css" />
  <![endif]-->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
    <meta http-equiv="X-UA-Compatible" content="IE=edge" >
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Titillium+Web:300italic,400,700,400italic,600italic' rel='stylesheet' type='text/css'>
    <script type="text/javascript" src="https://www.piperpal.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="https://www.piperpal.com/jquery.autocomplete.min.js"></script>
    <!-- FIXME
    <script type="text/javascript" src="https://www.piperpal.com/yaylocation-autocomplete.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-names.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-services.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-locations.php"></script>
    <script type="text/javascript" src="https://www.piperpal.com/piperpal-autocomplete-queries.php"></script>
    -->
    <meta name="viewport" content="width=620" />
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  <link rel="stylesheet" href="/resources/demos/style.css">
  <script>
   $(function() {
       $( "#simple-search-tourin" ).datepicker();
       $( "#simple-search-tourout" ).datepicker();
     });

        function success(position) {
        var s = document.querySelector('#status');
        
        if (s.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        s.innerHTML = '<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
        s.className = 'success';

        var q = document.querySelector('#status_publisher');
        
        if (q.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        q.innerHTML = '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

        // '<input type=text name=glat size=16 value=' + position.coords.latitude + ' /><input type=text name=glon size=16 value=' + position.coords.longitude + ' />';
        q.className = 'success';

        var r = document.querySelector('#status_lns');
        
        if (r.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        r.innerHTML =  '<img src="img/Latitude_Icon.png" title="Latitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /><br /><img src="img/Longitude_Icon.png" title="Longitude of Location-aware Content Tag" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' />';

//'<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
        r.className = 'success';

        var mapcanvas = document.createElement('div');
        mapcanvas.id = 'mapcanvas';
        mapcanvas.style.height = '400px';
        mapcanvas.style.width = '640px';
        
        document.querySelector('article').appendChild(mapcanvas);
        
        var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
        var myOptions = {
        zoom: 15,
        center: latlng,
        mapTypeControl: false,
        navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
        mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
        
        var marker = new google.maps.Marker({
                position: latlng, 
                                map: map, 
                                title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
                                });

        var locations = [
         ['Banja Luka', 44.766666699999990000, 17.183333299999960000, 4],
    ['Tuzla', 44.532841000000000000, 18.670499999999947000, 5],
    ['Zenica', 44.203439200000000000, 17.907743200000027000, 3],
    ['Sarajevo', 43.850000000000000000, 18.250000000000000000, 2],
    ['Mostar', 43.333333300000000000, 17.799999999999954000, 1]
];

var infowindow = new google.maps.InfoWindow();

var marker, i;
for (i = 0; i < locations.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][1], locations[i][2]),
      map: map
                                    });

google.maps.event.addListener(marker, 'click', (function (marker, i) {
    return function () {
        infowindow.setContent(locations[i][0]);
        infowindow.open(map, marker);
    }
                                                })(marker, i));
}
}

function error(msg) {
        // var s = document.querySelector('#status');
        // s.innerHTML = typeof msg == 'string' ? msg : "failed";
        // s.className = 'fail';
        
        // console.log(arguments);
}

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(success, error);
} else {
        error('not supported');
}

  function updateGeo() {
    var glat = document.getElementById("glat");
    var glon = document.getElementById("glon");
    
    glat.value = position.coords.latitude;
    glon.value = position.coords.longitude;

    alert(glat+","+glon);
  }
  </script>

    </head>
    <body style="background: #ffffff">
    <center>
    <a href="https://www.piperpal.com/"><img border="0" src="https://www.piperpal.com/piperpal.png" width="600" alt="Logo" /></a>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <script>
        function success(position) {
        var s = document.querySelector('#status');
        
        if (s.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        s.innerHTML = '<input type=hidden class="input_form_custom" name=glat value=' + position.coords.latitude + ' /><input type=hidden class="input_form_custom" name=glon value=' + position.coords.longitude + ' />';
        s.className = 'success';

        var q = document.querySelector('#status_publisher');
        
        if (q.className == 'success') {
                // not sure why we're hitting this twice in FF, I think it's to do with a cached result coming back    
                return;
        }
        
        q.innerHTML = '<div class="service_form input_form"><img src="img/icon2.png" alt="Icon2" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glat size=16 value=' + position.coords.latitude + ' /></div><div class="service_form input_form"><img src="img/icon2.png" alt="Icon2" class="icon_form" height="36" width="36"><input type=text class="input_form_custom" name=glon size=16 value=' + position.coords.longitude + ' /></div>';

        // '<input type=text name=glat size=16 value=' + position.coords.latitude + ' /><input type=text name=glon size=16 value=' + position.coords.longitude + ' />';
        q.className = 'success';
        
        var mapcanvas = document.createElement('div');
        mapcanvas.id = 'mapcanvas';
        mapcanvas.style.height = '400px';
        mapcanvas.style.width = '640px';
        
        document.querySelector('article').appendChild(mapcanvas);
        
        var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
        var myOptions = {
        zoom: 15,
        center: latlng,
        mapTypeControl: false,
        navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
        mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
        
        var marker = new google.maps.Marker({
                position: latlng, 
                                map: map, 
                                title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
                                });

        var locations = [
         ['Banja Luka', 44.766666699999990000, 17.183333299999960000, 4],
    ['Tuzla', 44.532841000000000000, 18.670499999999947000, 5],
    ['Zenica', 44.203439200000000000, 17.907743200000027000, 3],
    ['Sarajevo', 43.850000000000000000, 18.250000000000000000, 2],
    ['Mostar', 43.333333300000000000, 17.799999999999954000, 1]
];

var infowindow = new google.maps.InfoWindow();

var marker, i;
for (i = 0; i < locations.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][1], locations[i][2]),
      map: map
                                    });

google.maps.event.addListener(marker, 'click', (function (marker, i) {
    return function () {
        infowindow.setContent(locations[i][0]);
        infowindow.open(map, marker);
    }
                                                })(marker, i));
}
}

function error(msg) {
        var s = document.querySelector('#status');
        s.innerHTML = typeof msg == 'string' ? msg : "failed";
        s.className = 'fail';
        
        // console.log(arguments);
}

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(success, error);
} else {
        error('not supported');
}

</script>
   <form onsubmit='updateGeo()' id="searchbar-form" method='POST' action='https://api.piperpal.com/location/push.php'>
   <input type='hidden' name='c' value='INSERT' />
   <table cellpadding=5>
   <tr><td>Text:<input id="simple-search-location" class="input-large js-search-location" size=24 type=text name=name class=biginput id=name value='<?php echo $_GET['name']; ?>' placeholder='Example: FriendliestCoffeeShop' /></td></tr>
    <tr><td>Location:<input id="simple-search-location" class="input-large js-search-location" size=60 type=text name=location class=biginput id=location value='<?php if (!isset($_GET['location'])) { echo $_GET['location']; } else { echo 'https://www.piperpal.com/'; echo $_GET['service']; echo '/'; echo $_GET['name']; } ?>' /></td></tr>
   <tr><td>Service:<input id="simple-search-location" class="input-large js-search-location" size=24 type=text name=service class=biginput id=service value='<?php echo $_GET['service']; ?>' placeholder='Service' /></td></tr>
   <tr><td>Not Before:<input id="simple-search-tourin" class="input-large js-search-location" size=24 type=text name=notBefore class=biginput id=notBefore value='<?php echo $_GET['notBefore']; ?>' placeholder='Not Before' /></td></tr>
   <tr><td>Not After:<input id="simple-search-tourout" class="input-large js-search-location" size=24 type=text name=notAfter class=biginput id=notAfter value='<?php echo $_GET['notAfter']; ?>' placeholder='Not After'/></td></tr>
   <input id="simple-search-location" class="input-large js-search-location" size=24 type=hidden name=paid class=biginput id=paid value='<?php echo $_GET['paid']; ?>' placeholder='Price' />
   <div id='status'>
   <input id='glat' type='hidden' name='glat' placeholder='Latitude' size=32 value='37.42242580' />
   <input id='glon' type='hidden' name='glon' placeholder='Longitude' size=32 value='-122.08755550' />
   </div>
   <tr><td><form onsubmit='updateGeo()' action='https://api.piperpal.com/location/push.php' method='POST'>
   <script src='https://checkout.stripe.com/checkout.js' class='stripe-button' data-key='pk_live_51MsrtFAgJ7jHvJPRzksQbNY4573e98c9MPwsnOXymtKYWFUVgh6Bbm\
ZV9tPhhTwppFLDabbfm7Lkj9dEYaJBD9em00xNBVHJzf' data-amount='<?php echo $_GET['paid']; ?>' data-name='Aamot Software' data-description='<?php echo $_GET['location']; ?> / <?php echo $_GET['service']; ?> (<?php echo $_GET['paid']; ?>)' data-image='/img/Location_Icon.png'></script></td></tr>
   </table>
  </form>
</body>
</html>

Python Resolver Scripts

bin/gensource

#!/usr/bin/python

bin/indexer

# Written by Ole Aamot, 20211017

from cgi import parse_qs, escape
from urllib import quote_plus
import cgi
import urllib3

import hashlib
from math import radians, cos, sin, asin, sqrt
import textwrap
from cgi import parse_qs, escape
from bs4 import BeautifulSoup
import cgi
import time

def recursive_fetch(l,lat,lon):
    p = http.request('GET', l)
    o = p.data
    y = BeautifulSoup(o, "lxml")
    m = hashlib.sha256(p.data).hexdigest()
    locationtags = y.find_all("location")
    i = 0
    print locationtags
    while (i < len(locationtags)):
        name = y.findAll("location")[i]["name"]
        glat = y.findAll("location")[i]["lat"]
        glon = y.findAll("location")[i]["lon"]
   service = y.findAll("location")[i]["service"]
        data = y.findAll("location")[i]
        href = y.findAll("location")[i]["href"]
        r = haversine(float(glat),float(glon),float(lat),float(lon))
        print(gindex(r,name,m,href,data,glat,glon,lat,lon))
   linker = 'https://api.piperpal.com/location/robot.php?name=' + quote_plus(name.encode('utf-8'), safe=':/') + '&service=' + quote_plus(service.encode('utf-8'), safe=':/') + '&location=' + quote_plus(href.encode('utf-8'), safe=':/') + '&glat=' + glat + '&glon=' + glon + '&paid=1'
   insert = http.request('GET', linker)
   print linker
   print insert
   object = insert.data
# tester = BeautifulSoup(object, "lxml")
# macron = hashlib.sha256(insert.data).hexdigest(
        recursive_fetch(href,lat,lon)
        i = i + 1

def haversine(lat1, lon1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

def gindex(radius,n,d,l,query,my_lat,my_lon,lat,lon):
    return radius,n,d,l,query,my_lat,my_lon,lat,lon

http = urllib3.PoolManager()
q = 'Google'
l = 'http://aamot.software/piperpal.xml'
lat = '37.42242500'
lon = '-122.08755550'
service = 'Books'
recursive_fetch(l,lat,lon)

bin/piperpal

# Written by Ole Aamot, 20211017

from cgi import parse_qs, escape
from urllib import quote_plus
import cgi
import urllib3

import hashlib
from math import radians, cos, sin, asin, sqrt
import textwrap
from cgi import parse_qs, escape
from bs4 import BeautifulSoup
import cgi
import time

def recursive_fetch(l,lat,lon):
    p = http.request('GET', l)
    o = p.data
    y = BeautifulSoup(o, "lxml")
    m = hashlib.sha256(p.data).hexdigest()
    locationtags = y.find_all("location")
    i = 0
#    print locationtags
    while (i < len(locationtags)):
        name = y.findAll("location")[i]["name"]
        glat = y.findAll("location")[i]["lat"]
        glon = y.findAll("location")[i]["lon"]
   service = y.findAll("location")[i]["service"]
        data = y.findAll("location")[i]
        href = y.findAll("location")[i]["href"]
        recursive_fetch(href,glat,glon)
        r = haversine(float(glat),float(glon),float(lat),float(lon))
        print(gindex(r,name,m,href,data,glat,glon,lat,lon))
   linker = 'https://api.piperpal.com/location/robot.php?name=' + quote_plus(name.encode('utf-8'), safe=':/') + '&service=' + quote_plus(service.encode('utf-8'), safe=':/') + '&location=' + quote_plus(href.encode('utf-8'), safe=':/') + '&glat=' + glat + '&glon=' + glon + '&paid=1'
   insert = http.request('GET', linker)
   print linker
   print insert
   object = insert.data
# tester = BeautifulSoup(object, "lxml")
# macron = hashlib.sha256(insert.data).hexdigest()
   i = i + 1
        recursive_fetch(href,lat,lon)

def haversine(lat1, lon1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

def gindex(radius,n,d,l,query,my_lat,my_lon,lat,lon):
    return radius,n,d,l,query,my_lat,my_lon,lat,lon

http = urllib3.PoolManager()
q = 'Google'
l = 'https://www.aamotsoftware.com/piperpal.xml'
lat = '37.42242500'
lon = '-122.08755550'
service = 'Books'
recursive_fetch(l,lat,lon)

bin/genpiperpalsource

#!/usr/bin/perl

use CGI;
use DBI;

sub get_locations {
    my $c = CGI->new;
    my $dbh = DBI->connect("DBI:mysql:database=piperpal;host=piperpal.mysql.domeneshop.no", "piperpal", "xxxxxxxx", {'RaiseError' => 1});
    print "<?xml version='1.0'?>\n";
    print "<piperpal version='2.0'>\n";
    $dbh->do ("SELECT DISTINCT email,name,glat,glon,location,modified,created,service,paid FROM piperpal WHERE modified < NOW() and created > NOW();");
    my $sth = $dbh->prepare ("SELECT DISTINCT email,name,glat,glon,location,modified,created,service,paid FROM piperpal WHERE modified < NOW() and created > NOW() ORDER by name;");
    $sth->execute();
    while (my $ref = $sth->fetchrow_hashref()) {
                print "<location src='http://api.piperpal.com/location' service='" . $ref->{'service'} . ":" . $ref->{'email'} . "' name='" . $ref->{'name'} . "' lat='" . $ref->{'glat'} . "' lon='" . $ref->{'glon'} . "' href='" . $ref->{'location'} . "' notbefore='" . $ref->{'modified'} . "' notafter='" . $ref->{'created'} . "' paid='" . $ref->{'paid'} . "'>" . $ref->{'name'} . "</location>\n";
    }
    $sth->finish();
    $dbh->disconnect();
    print "</piperpal>\n";
    return;
}
&get_locations;

bin/resolver

# Written by Ole Aamot, 20200409

from cgi import parse_qs, escape
from urllib import quote_plus
import cgi
import urllib3
import mysql.connector
from mysql.connector import Error
import hashlib
from math import radians, cos, sin, asin, sqrt
import textwrap
from cgi import parse_qs, escape
from bs4 import BeautifulSoup
import cgi
import time

def piperpal_resolver(l,n,s,lat,lon):
    p = http.request('GET', l)
    o = p.data
    y = BeautifulSoup(o, "lxml")
    m = hashlib.sha256(p.data).hexdigest()
    locationtags = y.find_all("location")
    i = 0
    print locationtags
    while (i < len(locationtags)):
        name = y.findAll("location")[i]["name"]
        glat = y.findAll("location")[i]["lat"]
        glon = y.findAll("location")[i]["lon"]
        service = y.findAll("location")[i]["service"]
        data = y.findAll("location")[i]
        href = y.findAll("location")[i]["href"]
        r = haversine(float(glat),float(glon),float(lat),float(lon))
#        print map
        print(gindex(r,name,m,href,data,glat,glon,lat,lon))
        linker = 'https://api.piperpal.com/resolver/?name=' + quote_plus(name.encode('utf-8'), safe=':/') + '&service=' + quote_plus(service.encode('utf-8'), safe=':/') + '&location=' + quote_plus(href.encode('utf-8'), safe=':/') + '&glat=' + glat + '&glon=' + glon + '&paid=1'
        insert = http.request('GET', linker)
        print linker
        print insert
        object = insert.data
#       tester = BeautifulSoup(object, "lxml")
#       macron = hashlib.sha256(insert.data).hexdigest()
        i = i + 1
        piperpal_resolver(href,s,n,lat,lon)
    return (y,i)

def haversine(lat1, lon1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

def gindex(radius,n,d,l,query,my_lat,my_lon,lat,lon):
    return radius,n,d,l,query,my_lat,my_lon,lat,lon
services = dict()
services = ('Restaurant','Bar','Concert','Film','Books','Health','Clothes','Food','Music','Electronics','Transport','Rental')
http = urllib3.PoolManager()
q = 'Wikipedia'
p = 1
l = 'http://www.piperpal.com/piperpal.xml';
lat = '37.42242500'
lon = '-122.08755550'
service = 'Books'
for x in range(-90, 91):
    for y in range(-180, 181):
           print x,y,lat,lon,q,l,0
           print x,y,lat,lon,q,l,1
           for z in services:
#                if (z=="Restaurant"):
                 print z,x,y,lat,lon,q,l,1
#                 print "Restaurant"
                 piperpal_resolver(l,1,z,lat,lon)

Cron Jobs

0 * * * *  /bin/piperpal

The "piperpal" cron job runs every hour and executes the Python script which runs recursive fetch of the XML file https://www.aamotsoftware.com/piperpal.xml for processing into the database.

0 * * * * python  /bin/indexer

The "indexer" cron job runs every hour and executes the Python script which runs recursive fetch of the XML file https://aamot.software/piperpal.xml for processing into the index via https://api.piperpal.com/location/robot.php?name=&service&location&glat&glon&paid=1

0 * * * *  /bin/genpiperpalsource >piperpal/piperpal.xml

The "genpiperpalsource" cron job runs every hour and write the file https://www.aamotsoftware.com/piperpal.xml) from the SQL database from the Perl script "genpiperpalsource".

Mobile App

Android - https://www.github.com/piperpal/android

https://www.piperpal.com/apk/piperpal.apk

iOS - https://www.github.com/piperpal/ios

Web App

World Wide Web - https://www.geopher.com/

https://www.geopher.com/

Node/Express Module

Location Data Server - https://www.npmjs.com/package/location-server

Node/Express is a open source framework for building web sites in the NodeJS language.

"Location Data Server" is a module for accessing the Location API (https://api.piperpal.com/location/json.php) from Node/Express.

So far you can download the "Location Data Server" NodeJS source code from https://gitlab.com/ole.aamot/location-server and the NPMJS package from https://www.npmjs.com/package/location-server

You install it with Node Package Manager (NPM) in Terminal with

npm i location-server

You can view the implementation of location-server for the Piperpal Location API at https://gitlab.com/ole.aamot/location-server/-/blob/main/location-server.cjs?ref_type=heads:

const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');

const app = express();
const port = 3000;

app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.get('/location-server-time', async (req, res) => {
    const { timeOut, timeBegin, timeEnd } = req.query;
    try {
        const response = new Date().getTime();
        res.json(response);
    } catch (error) {
        res.status(500).json({ error: 'Error fetching time' });
    }
});

app.get('/location-server-data', async (req, res) => {
    const { service, glat, glon, radius } = req.query;
    try {
        const response = await axios.get(`https://api.piperpal.com/location/json.php?service=${service}&glat=${glat}&glon=${glon}&radius=${radius}`);
        res.json(response.data);
        const locations = response.data.locations;
    } catch (error) {
        res.status(500).json({ error: 'Error fetching data' });
    }
});

app.listen(port, () => {
    console.log(`Location Data Server listening on port ${port}`);
});

Location Mobile - https://www.piperpal.com/mobile/

https://www.piperpal.com/mobile/
CREATE TABLE piperpal (
       id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
       name VARCHAR(100) NOT NULL DEFAULT '',
       service VARCHAR(1024) NOT NULL,
       location VARCHAR(1024) NOT NULL,
       modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       created TIMESTAMP NULL DEFAULT NULL,
       glat DECIMAL(10, 8) NOT NULL,
       glon DECIMAL(11, 8) NOT NULL, 
       paid MEDIUMINT(16) UNSIGNED NOT NULL,
       token VARCHAR(32) NOT NULL,
       type VARCHAR(32) NOT NULL,
       email VARCHAR(256) NOT NULL,
       PRIMARY KEY (id)
);

Haversine Computation of Piperpal Geolocations

SELECT DISTINCT
id,name,service,location,modified,created,glat,glon,pa
id,token,type,email,111.045*DEGREES(ACOS(COS(RADIANS(l
atpoint))*COS(RADIANS(glat))*COS(RADIANS(longpoint)-RA
DIANS(glon))+SIN(RADIANS(latpoint))*SIN(RADIANS(glat
)))) AS distance_in_km FROM piperpal JOIN (SELECT " .
$_POST['latitude'] . " AS latpoint, " .
$_POST['longitude'] . " AS longpoint) AS p ON 1=1
WHERE name = '" . $_POST['location'] . "' ORDER BY
distance_in_km;