main
Ilham Wara Nugroho 2026-07-21 15:18:09 +07:00
parent 8c0968e5c6
commit 56be7efdaf
49 changed files with 1638 additions and 615 deletions

View File

@ -22,6 +22,8 @@ public class HomeController : Controller
{
//memanggil data lokasi dari master DB Lokasi
ViewBag.lokasiHome = await db.Lokasi
.Include(x => x.LokasiFauna)
.Include(x => x.LokasiTumbuhan)
.OrderByDescending(l => l.MsLokasiId)
.Take(3)
.ToListAsync();
@ -34,19 +36,24 @@ public class HomeController : Controller
.OrderByDescending(l => l.MsFaunaId)
.Take(4)
.ToListAsync();
var model = new HomeViewModel
{
Statistik = new StatistikHomeModel
{
TotalLocations = 10,
TotalFlora = 50,
TotalFauna = 30,
TotalSpecies = 80
},
};
return View(model);
ViewBag.TotalLokasi = await db.Lokasi.CountAsync();
ViewBag.TotalTumbuhan = await db.Tumbuhan.CountAsync();
ViewBag.TotalFauna = await db.Fauna.CountAsync();
ViewBag.Total = (ViewBag.TotalTumbuhan+ViewBag.TotalFauna);
// var model = new HomeViewModel
// {
// Statistik = new StatistikHomeModel
// {
// TotalLocations = 10,
// TotalFlora = 50,
// TotalFauna = 30,
// TotalSpecies = 80
// },
// };
return View();
}
public IActionResult Privacy()

View File

@ -2,6 +2,7 @@ using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using kehati.Models.View;
using kehati.Database;
using kehati.Helpers;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -17,208 +18,21 @@ namespace kehati.Controllers
public async Task<IActionResult> Index(int page = 1)
{
ViewBag.lokasiHome = await Pagination.PaginateAsync(
db.Lokasi.OrderByDescending(l => l.MsLokasiId),
db.Lokasi
.Include(x => x.LokasiFauna)
.Include(x => x.LokasiTumbuhan)
.OrderByDescending(l => l.MsLokasiId),
page,12);
return View();
}
public IActionResult Detail(string slug)
public async Task<IActionResult> Detail(string slug)
{
ViewBag.Slug = slug;
var lokasi = new LokasiModel
{
Slug = "tebet-eco-park",
Name = "Tebet Eco Park",
Region = "Jakarta Selatan",
Area = "15.3 Ha",
FloraCount = 45,
FaunaCount = 20,
Total = 100,
Description = "Taman kota modern yang mengintegrasikan ekologi dan ruang publik. Rumah bagi puluhan jenis tanaman lokal serta berbagai burung dan serangga penyerbuk.",
Image = "loc-tebet.jpg"
};
var model = new HomeViewModel
{
Location = lokasi,
FeaturedSpesies = new List<SpesiesModel>
{
new()
{
Slug = "pohon-trembesi",
Type = "flora",
CommonName = "Pohon Trembesi",
ScientificName = "Samanea saman",
Description =
"Pohon peneduh raksasa dengan tajuk lebar menyerupai payung. Sangat efektif menyerap karbon dioksida sehingga banyak ditanam di ruang publik Jakarta.",
Habitat = "Tumbuh baik di dataran rendah tropis, tanah subur, sinar matahari penuh.",
ConservationStatus = "Aman",
Image = "sp-trembesi.jpg",
LocationSlugs = new List<string>
{
"tebet-eco-park",
"hutan-kota-gbk",
"taman-menteng"
}
},
new()
{
Slug= "pohon-beringin",
Type= "flora",
CommonName= "Pohon Beringin",
ScientificName= "Ficus benjamina",
Description=
"Pohon rindang dengan akar udara khas yang menjuntai. Simbol keteduhan dan sering dijumpai di taman kota serta ruang publik Jakarta.",
Habitat= "Iklim tropis, tanah lembab, tahan terhadap polusi udara perkotaan.",
ConservationStatus= "Aman",
Image= "sp-beringin.jpg",
LocationSlugs = new List<string>
{"hutan-kota-srengseng", "taman-menteng", "hutan-kota-gbk"}
},
new()
{
Slug= "mangrove-rhizophora",
Type= "flora",
CommonName= "Bakau Merah",
ScientificName= "Rhizophora mucronata",
Description=
"Tumbuhan bakau dengan akar tunjang khas. Berfungsi sebagai benteng alami pesisir Jakarta terhadap abrasi dan intrusi air laut.",
Habitat= "Kawasan pesisir berlumpur, muara sungai, air payau.",
ConservationStatus= "Dilindungi",
Image= "sp-mangrove.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
},
new()
{
Slug= "bunga-kamboja",
Type= "flora",
CommonName= "Kamboja Putih",
ScientificName= "Plumeria alba",
Description=
"Pohon hias berbunga harum dengan kelopak putih dan kuning di tengah. Populer di pekarangan dan taman kota.",
Habitat= "Daerah tropis kering, tanah berdrainase baik.",
ConservationStatus= "Aman",
Image= "sp-kamboja.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "taman-menteng"}
},
new()
{
Slug= "anggrek-bulan",
Type= "flora",
CommonName= "Anggrek Bulan",
ScientificName= "Phalaenopsis amabilis",
Description=
"Bunga nasional Indonesia (Puspa Pesona). Berkelopak lebar putih murni, tumbuh menempel pada batang pohon.",
Habitat= "Epifit pada pohon di hutan tropis lembab.",
ConservationStatus= "Rentan",
Image= "sp-anggrek.jpg",
LocationSlugs = new List<string>
{"hutan-kota-srengseng", "tebet-eco-park"}
},
new()
{
Slug= "bambu-kuning",
Type= "flora",
CommonName= "Bambu Kuning",
ScientificName= "Bambusa vulgaris",
Description=
"Rumpun bambu berbatang kuning cerah yang tumbuh cepat. Berperan penting menyerap air tanah dan mencegah erosi.",
Habitat= "Tanah lembab di tepi sungai, taman, dan hutan kota.",
ConservationStatus= "Aman",
Image= "sp-bambu.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "hutan-kota-srengseng"}
},
new()
{
Slug= "burung-kutilang",
Type= "fauna",
CommonName= "Burung Kutilang",
ScientificName= "Pycnonotus aurigaster",
Description=
"Burung pengicau kecil dengan tunggir kuning cerah. Salah satu burung liar paling umum di taman-taman Jakarta.",
Habitat= "Taman kota, pekarangan, hutan sekunder.",
ConservationStatus= "Aman",
Image= "sp-kutilang.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "taman-menteng", "hutan-kota-gbk"}
},
new()
{
Slug= "burung-madu-sriganti",
Type= "fauna",
CommonName= "Burung Madu Sriganti",
ScientificName= "Cinnyris jugularis",
Description=
"Burung kecil berwarna cerah, jantan berdada hitam berkilau. Penghisap nektar bunga di taman dan hutan kota.",
Habitat= "Taman berbunga, semak berbunga, pinggir hutan.",
ConservationStatus= "Dilindungi",
Image= "sp-madu-sriganti.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "hutan-kota-srengseng", "mangrove-pik"}
},
new()
{
Slug= "kupu-kupu-raja",
Type= "fauna",
CommonName= "Kupu-kupu Raja",
ScientificName= "Papilio memnon",
Description=
"Kupu-kupu besar berwarna hitam kebiruan dengan sayap lebar. Penyerbuk penting bagi berbagai tanaman berbunga.",
Habitat= "Taman berbunga, hutan sekunder, pinggir sungai.",
ConservationStatus= "Aman",
Image= "sp-kupu-kupu.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "hutan-kota-srengseng"}
},
new()
{
Slug= "biawak-air",
Type= "fauna",
CommonName= "Biawak Air",
ScientificName= "Varanus salvator",
Description=
"Reptil besar semi-akuatik dengan lidah bercabang. Predator alami yang membantu mengendalikan populasi tikus di ekosistem kota.",
Habitat= "Rawa, sungai, hutan mangrove.",
ConservationStatus= "Dilindungi",
Image= "sp-biawak.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
},
new()
{
Slug= "monyet-ekor-panjang",
Type= "fauna",
CommonName= "Monyet Ekor Panjang",
ScientificName= "Macaca fascicularis",
Description=
"Primata berbulu abu-abu kecoklatan dengan ekor panjang. Hidup berkelompok di kawasan hutan yang tersisa.",
Habitat= "Hutan mangrove, hutan sekunder, tepi sungai.",
ConservationStatus= "Rentan",
Image= "sp-monyet.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
},
new()
{
Slug= "elang-bondol",
Type= "fauna",
CommonName= "Elang Bondol",
ScientificName= "Haliastur indus",
Description=
"Elang berkepala putih dengan tubuh coklat kemerahan. Maskot Provinsi DKI Jakarta dan simbol kekayaan hayati pesisir.",
Habitat= "Pesisir, mangrove, muara sungai.",
ConservationStatus= "Dilindungi",
Image= "sp-elang-bondol.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
}
}
};
return View(model);
var decode = Custom.DecodeInt(slug);
ViewBag.data = await db.Lokasi.FirstOrDefaultAsync(x => x.MsLokasiId == decode);
ViewBag.lokasiTumbuhan = await db.LokasiTumbuhan.Include(x => x.Tumbuhan).Where(x => x.MsLokasiId == decode).ToListAsync();
ViewBag.lokasiFauna = await db.LokasiFauna.Include(x => x.Fauna).Where(x => x.MsLokasiId == decode).ToListAsync();
return View();
}
}
}

View File

@ -1,56 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using kehati.Database;
using kehati.Models.View;
using Microsoft.EntityFrameworkCore;
namespace kehati.Controllers
{
public class MapController : Controller
{
public IActionResult Index()
{
var model = new HomeViewModel
{
FeaturedLocations = new List<LokasiModel>
{
new()
{
Slug = "tebet-eco-park",
Name = "Tebet Eco Park",
Region = "Jakarta Selatan",
Area = "15.3 Ha",
Latitude = "-6.236993826064424",
Longitude = "106.85290802883573",
FloraCount = 45,
FaunaCount = 20,
Image = "loc-tebet.jpg"
},
new()
{
Slug = "hutan-kota-srengseng",
Name = "Hutan Kota Srengseng",
Image = "loc-srengseng.jpg",
Region = "Jakarta Barat",
Area = "15.3 Ha",
Latitude = "",
Longitude = "",
FloraCount = 45,
FaunaCount = 20
},
private readonly ApplicationDbContext db;
new()
{
Slug = "mangrove-angke",
Name = "Hutan Mangrove Angke",
Region = "Jakarta Barat",
Area = "15.3 Ha",
Latitude = "",
Longitude = "",
FloraCount = 45,
FaunaCount = 20,
Image = "loc-mangrove-pik.jpg"
}
}
};
return View(model);
public MapController(ApplicationDbContext context)
{
db = context;
}
public async Task<IActionResult> Index()
{
ViewBag.lokasiHome = await db.Lokasi
.Where(x => x.Lat != null)
.Include(x => x.LokasiFauna)
.Include(x => x.LokasiTumbuhan)
.OrderByDescending(l => l.MsLokasiId)
.ToListAsync();
return View();
}
public IActionResult Detail(string slug)

View File

@ -20,6 +20,7 @@ namespace kehati.Database
public DbSet<Group> Group { get; set; }
public DbSet<Habitat> Habitat { get; set; }
public DbSet<LokasiTumbuhan> LokasiTumbuhan { get; set; }
public DbSet<LokasiFauna> LokasiFauna { get; set; }
public DbSet<Menu> Menu { get; set; }
public DbSet<Tumbuhan> Tumbuhan { get; set; }
public DbSet<Fauna> Fauna { get; set; }

109
Helpers/Custom.cs 100644
View File

@ -0,0 +1,109 @@
namespace kehati.Helpers;
using System.Security.Cryptography;
using System.Text;
using kehati.Models.Common;
using Microsoft.EntityFrameworkCore;
public static class Custom
{
// Ganti dengan secret Anda sendiri
private const string Secret = "kehatiDINASLHDKI-2026";
private static byte[] GetKey()
{
return MD5.HashData(Encoding.UTF8.GetBytes(Secret));
}
private static byte[] GetIV()
{
byte[] sha = SHA1.HashData(Encoding.UTF8.GetBytes(Secret));
return sha.Take(16).ToArray();
}
public static string Encode(int value)
{
return Encode(value.ToString());
}
public static string Encode(string value)
{
string random = RandomString(4);
string text = random + value;
using var aes = Aes.Create();
aes.Key = GetKey();
aes.IV = GetIV();
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using var encryptor = aes.CreateEncryptor();
byte[] bytes = Encoding.UTF8.GetBytes(text);
byte[] encrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
string hex = Convert.ToHexString(encrypted).ToLower();
return FormatUuid(hex);
}
public static string Decode(string value)
{
value = value.Replace("-", "");
byte[] encrypted = Convert.FromHexString(value);
using var aes = Aes.Create();
aes.Key = GetKey();
aes.IV = GetIV();
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using var decryptor = aes.CreateDecryptor();
byte[] plain = decryptor.TransformFinalBlock(
encrypted,
0,
encrypted.Length);
string result = Encoding.UTF8.GetString(plain);
// Hilangkan random 4 karakter
return result.Substring(4);
}
public static int DecodeInt(string value)
{
return int.Parse(Decode(value));
}
private static string RandomString(int length)
{
const string chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Span<byte> bytes = stackalloc byte[length];
RandomNumberGenerator.Fill(bytes);
var sb = new StringBuilder(length);
foreach (byte b in bytes)
sb.Append(chars[b % chars.Length]);
return sb.ToString();
}
private static string FormatUuid(string hex)
{
return
$"{hex[..8]}-" +
$"{hex.Substring(8, 4)}-" +
$"{hex.Substring(12, 4)}-" +
$"{hex.Substring(16, 4)}-" +
$"{hex.Substring(20)}";
}
}

View File

@ -0,0 +1,362 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using kehati.Database;
#nullable disable
namespace kehati.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20260721071042_LokasiFauna")]
partial class LokasiFauna
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("kehati.Models.Entity.Master.Famili", b =>
{
b.Property<int>("MsFamiliId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFamiliId"));
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("MsFamiliId");
b.ToTable("ms_famili");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Fauna", b =>
{
b.Property<int>("MsFaunaId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFaunaId"));
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<string>("MsFamiliId")
.HasColumnType("text")
.HasColumnName("ms_famili_id");
b.Property<string>("MsHabitusId")
.HasColumnType("text")
.HasColumnName("ms_habitus_id");
b.Property<string>("NamaIlmiah")
.HasColumnType("text")
.HasColumnName("nama_ilmiah");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.HasKey("MsFaunaId");
b.ToTable("ms_fauna");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Group", b =>
{
b.Property<int>("MsGroupId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsGroupId"));
b.Property<string>("Alias")
.HasColumnType("text")
.HasColumnName("alias");
b.Property<int?>("CreatedBy")
.HasColumnType("integer")
.HasColumnName("created_by");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.Property<int?>("UpdatedBy")
.HasColumnType("integer")
.HasColumnName("updated_by");
b.HasKey("MsGroupId");
b.ToTable("ms_group");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Habitat", b =>
{
b.Property<int>("MsHabitusId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsHabitusId"));
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("MsHabitusId");
b.ToTable("ms_habitus");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Lokasi", b =>
{
b.Property<int>("MsLokasiId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsLokasiId"));
b.Property<string>("Area")
.HasColumnType("text")
.HasColumnName("area");
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<int?>("Kode")
.HasColumnType("integer")
.HasColumnName("kode");
b.Property<string>("Lat")
.HasColumnType("text")
.HasColumnName("lat");
b.Property<string>("Long")
.HasColumnType("text")
.HasColumnName("long");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Region")
.HasColumnType("text")
.HasColumnName("region");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.HasKey("MsLokasiId");
b.ToTable("ms_lokasi");
});
modelBuilder.Entity("kehati.Models.Entity.Master.LokasiTumbuhan", b =>
{
b.Property<int>("MsLokasiTumbuhanId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsLokasiTumbuhanId"));
b.Property<int>("MsLokasiId")
.HasColumnType("integer")
.HasColumnName("ms_lokasi_id");
b.Property<int>("MsTumbuhanId")
.HasColumnType("integer")
.HasColumnName("ms_tumbuhan_id");
b.HasKey("MsLokasiTumbuhanId");
b.HasIndex("MsLokasiId");
b.HasIndex("MsTumbuhanId");
b.ToTable("ms_lokasi_tumbuhan");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Menu", b =>
{
b.Property<int>("MsMenuId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsMenuId"));
b.Property<string>("MenuIcon")
.HasColumnType("text")
.HasColumnName("menu_icon");
b.Property<string>("MenuType")
.HasColumnType("text")
.HasColumnName("menu_type");
b.Property<string>("Module")
.HasColumnType("text")
.HasColumnName("module");
b.Property<string>("Ordering")
.HasColumnType("text")
.HasColumnName("ordering");
b.Property<int?>("ParentId")
.HasColumnType("integer")
.HasColumnName("parent_id");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.Property<string>("Title")
.HasColumnType("text")
.HasColumnName("title");
b.Property<string>("Url")
.HasColumnType("text")
.HasColumnName("url");
b.HasKey("MsMenuId");
b.ToTable("ms_menu");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Tumbuhan", b =>
{
b.Property<int>("MsTumbuhanId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsTumbuhanId"));
b.Property<string>("Cites")
.HasColumnType("text")
.HasColumnName("cites");
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<string>("Iucn")
.HasColumnType("text")
.HasColumnName("iucn");
b.Property<int>("MsFamiliId")
.HasColumnType("integer")
.HasColumnName("ms_famili_id");
b.Property<int>("MsHabitatId")
.HasColumnType("integer")
.HasColumnName("ms_habitus_id");
b.Property<string>("NamaIlmiah")
.HasColumnType("text")
.HasColumnName("name_ilmiah");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("StatusPerlindungan")
.HasColumnType("text")
.HasColumnName("status_perlindungan");
b.Property<bool>("TanamanKhasJakarta")
.HasColumnType("boolean")
.HasColumnName("tanaman_khas_jakarta");
b.HasKey("MsTumbuhanId");
b.ToTable("ms_tumbuhan");
});
modelBuilder.Entity("kehati.Models.Entity.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<int>("MsGroupId")
.HasColumnType("integer")
.HasColumnName("ms_group_id");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("users");
});
modelBuilder.Entity("kehati.Models.Entity.Master.LokasiTumbuhan", b =>
{
b.HasOne("kehati.Models.Entity.Master.Lokasi", "Lokasi")
.WithMany()
.HasForeignKey("MsLokasiId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("kehati.Models.Entity.Master.Tumbuhan", "Tumbuhan")
.WithMany()
.HasForeignKey("MsTumbuhanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Lokasi");
b.Navigation("Tumbuhan");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,47 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace kehati.Migrations
{
/// <inheritdoc />
public partial class LokasiFauna : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ms_lokasi_fauna",
columns: table => new
{
MsLokasiFaunaId = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ms_lokasi_id = table.Column<int>(type: "integer", nullable: false),
ms_fauna_id = table.Column<int>(type: "integer", nullable: false),
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
},
constraints: table =>
{
table.PrimaryKey("PK_MsLokasiFaunaId", x => x.MsLokasiFaunaId);
table.ForeignKey(
name: "FK_LokasiId",
column: x => x.ms_lokasi_id,
principalTable: "ms_lokasi",
principalColumn: "MsLokasiId");
table.ForeignKey(
name: "FK_FaunaId",
column: x => x.ms_fauna_id,
principalTable: "ms_fauna",
principalColumn: "MsFaunaId");
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -30,14 +30,55 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFamiliId"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("MsFamiliId");
b.ToTable("ms_famili");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Fauna", b =>
{
b.Property<int>("MsFaunaId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFaunaId"));
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<string>("MsFamiliId")
.HasColumnType("text")
.HasColumnName("ms_famili_id");
b.Property<string>("MsHabitusId")
.HasColumnType("text")
.HasColumnName("ms_habitus_id");
b.Property<string>("NamaIlmiah")
.HasColumnType("text")
.HasColumnName("nama_ilmiah");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.HasKey("MsFaunaId");
b.ToTable("ms_fauna");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Group", b =>
{
b.Property<int>("MsGroupId")
@ -47,22 +88,24 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsGroupId"));
b.Property<string>("Alias")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("alias");
b.Property<int>("CreatedBy")
.HasColumnType("integer");
b.Property<int?>("CreatedBy")
.HasColumnType("integer")
.HasColumnName("created_by");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("status");
b.Property<int>("UpdatedBy")
.HasColumnType("integer");
b.Property<int?>("UpdatedBy")
.HasColumnType("integer")
.HasColumnName("updated_by");
b.HasKey("MsGroupId");
@ -78,8 +121,8 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsHabitusId"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("MsHabitusId");
@ -106,6 +149,14 @@ namespace kehati.Migrations
.HasColumnType("integer")
.HasColumnName("kode");
b.Property<string>("Lat")
.HasColumnType("text")
.HasColumnName("lat");
b.Property<string>("Long")
.HasColumnType("text")
.HasColumnName("long");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
@ -146,6 +197,10 @@ namespace kehati.Migrations
b.HasKey("MsLokasiTumbuhanId");
b.HasIndex("MsLokasiId");
b.HasIndex("MsTumbuhanId");
b.ToTable("ms_lokasi_tumbuhan");
});
@ -158,38 +213,36 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsMenuId"));
b.Property<string>("MenuIcon")
.IsRequired()
.HasColumnType("text")
.HasColumnName("menu_icon");
b.Property<string>("MenuType")
.IsRequired()
.HasColumnType("text")
.HasColumnName("menu_type");
b.Property<string>("Module")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("module");
b.Property<string>("Ordering")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("ordering");
b.Property<int>("ParentId")
b.Property<int?>("ParentId")
.HasColumnType("integer")
.HasColumnName("parent_id");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("status");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("title");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
.HasColumnType("text")
.HasColumnName("url");
b.HasKey("MsMenuId");
@ -281,6 +334,25 @@ namespace kehati.Migrations
b.ToTable("users");
});
modelBuilder.Entity("kehati.Models.Entity.Master.LokasiTumbuhan", b =>
{
b.HasOne("kehati.Models.Entity.Master.Lokasi", "Lokasi")
.WithMany()
.HasForeignKey("MsLokasiId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("kehati.Models.Entity.Master.Tumbuhan", "Tumbuhan")
.WithMany()
.HasForeignKey("MsTumbuhanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Lokasi");
b.Navigation("Tumbuhan");
});
#pragma warning restore 612, 618
}
}

View File

@ -21,4 +21,13 @@ public class Lokasi
public string? Region { get; set; } = "";
[Column("area")]
public string? Area { get; set; } = "";
[Column("lat")]
public string? Lat { get; set; } = "";
[Column("long")]
public string? Long { get; set; } = "";
public ICollection<LokasiTumbuhan> LokasiTumbuhan { get; set; } = new List<LokasiTumbuhan>();
public ICollection<LokasiFauna> LokasiFauna { get; set; } = new List<LokasiFauna>();
}

View File

@ -0,0 +1,23 @@
namespace kehati.Models.Entity.Master;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
[Table("ms_lokasi_fauna")]
public class LokasiFauna
{
[Key]
public int MsLokasiFaunaId { get; set; }
[Column("ms_fauna_id")]
public int MsFaunaId { get; set; }
[Column("ms_lokasi_id")]
public int MsLokasiId { get; set; }
//contoh untuk one to many
// public ICollection<Tumbuhan> Tumbuhan { get; set; } = new List<Tumbuhan>();
//ini one to one
[ForeignKey(nameof(MsFaunaId))]
public Fauna Fauna { get; set; } = null!;
[ForeignKey(nameof(MsLokasiId))]
public Lokasi Lokasi { get; set; } = null!;
}

View File

@ -10,4 +10,14 @@ public class LokasiTumbuhan
public int MsTumbuhanId { get; set; }
[Column("ms_lokasi_id")]
public int MsLokasiId { get; set; }
//contoh untuk one to many
// public ICollection<Tumbuhan> Tumbuhan { get; set; } = new List<Tumbuhan>();
//ini one to one
[ForeignKey(nameof(MsTumbuhanId))]
public Tumbuhan Tumbuhan { get; set; } = null!;
[ForeignKey(nameof(MsLokasiId))]
public Lokasi Lokasi { get; set; } = null!;
}

View File

@ -1,3 +1,4 @@
@using kehati.Helpers
@using kehati.Models.View
@using kehati.Models.Entity.Master
@using kehati.Models.Common
@ -20,7 +21,7 @@
Katalog
</div>
<h1 class="mt-3 font-serif text-5xl leading-tight text-foreground">
Flora &amp; Fauna Jakarta
Fauna Jakarta
</h1>
<p class="mt-4 text-lg text-muted-foreground">
Telusuri spesies yang terdokumentasi di kawasan konservasi Jakarta.
@ -43,13 +44,13 @@
<option value="fauna" selected="@(Model.Type=="fauna")">Fauna</option>
</select>
<select name="status" class="w-full rounded-lg border border-input bg-background px-3 py-2">
<option value="all" selected="@(Model.Status == "all")">Semua Status</option>
<option value="Aman" selected="@(Model.Status == "Aman")">Aman</option>
<option value="Rentan" selected="@(Model.Status == "Rentan")">Rentan</option>
<option value="Terancam" selected="@(Model.Status == "Terancam")">Terancam</option>
<option value="Kritis" selected="@(Model.Status == "Kritis")">Kritis</option>
<option value="Dilindungi" selected="@(Model.Status == "Dilindungi")">Dilindungi</option>
</select>
<option value="all" selected="@(Model.Status == "all")">Semua Status</option>
<option value="Aman" selected="@(Model.Status == "Aman")">Aman</option>
<option value="Rentan" selected="@(Model.Status == "Rentan")">Rentan</option>
<option value="Terancam" selected="@(Model.Status == "Terancam")">Terancam</option>
<option value="Kritis" selected="@(Model.Status == "Kritis")">Kritis</option>
<option value="Dilindungi" selected="@(Model.Status == "Dilindungi")">Dilindungi</option>
</select>
<select name="lokasi" class="w-full rounded-lg border border-input bg-background px-3 py-2">
<option value="all">Semua Lokasi</option>
@foreach(LokasiModel loc in Model.FeaturedLocations)
@ -83,43 +84,42 @@
@foreach(var s in fauna.Items)
{
<a asp-controller="katalog"
asp-action="detail"
asp-route-slug="@s.Slug"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image"
alt="@s.Name"
loading="lazy"
asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
asp-action="detail"
asp-route-slug="@Custom.Encode(s.MsFaunaId)" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image"
alt="@s.Name"
loading="lazy"
asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
Fauna
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
Fauna
</div>
</div>
</div>
<!-- Content -->
<div class="p-4">
<div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground">
@s.Name
</h3>
<!-- Content -->
<div class="p-4">
<div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground">
@s.Name
</h3>
</div>
<p class="mt-0.5 text-xs italic text-muted-foreground">
@s.NamaIlmiah
</p>
<!-- Status Badge -->
<div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.Status)
? statusColor[s.Status]
: "")">
@s.Status
</span>
</div>
</div>
<p class="mt-0.5 text-xs italic text-muted-foreground">
@s.NamaIlmiah
</p>
<!-- Status Badge -->
<div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.Status)
? statusColor[s.Status]
: "")">
@s.Status
</span>
</div>
</div>
</a>
</a>
}
</div>
}

View File

@ -1,6 +1,7 @@
@using kehati.Models.View
@using kehati.Models.Entity.Master
@using kehati.Models.Common
@using kehati.Helpers
@{
ViewData["Title"] = "Katalog";
var tumbuhan = ViewBag.tumbuhanHome as PagedResult<Tumbuhan>;
@ -84,7 +85,7 @@
{
<a asp-controller="katalog"
asp-action="detail"
asp-route-slug="@s.Slug"
asp-route-slug="@Custom.Encode(s.MsTumbuhanId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">

View File

@ -1,4 +1,5 @@
@using kehati.Models.View
@using kehati.Helpers
@{
ViewData["Title"] = "Beranda";
var statusColor = new Dictionary<string, string>
@ -52,11 +53,11 @@
Jelajahi Lokasi
<i data-lucide="arrow-right" class="h-4 w-4"></i>
</a>
<a asp-controller="katalog"
@* <a asp-controller="katalog"
asp-action="Index"
class="inline-flex items-center gap-2 rounded-lg border border-border bg-background/80 px-5 py-3 text-sm font-medium text-foreground backdrop-blur transition-colors hover:bg-secondary">
Lihat Katalog
</a>
</a> *@
</div>
</div>
</div>
@ -64,39 +65,39 @@
<!-- STATISTIK SECTION -->
<section class="border-y border-border/60 bg-secondary/30">
<div class="mx-auto grid max-w-7xl grid-cols-2 divide-x divide-border/60 px-4 sm:px-6 lg:grid-cols-4 lg:px-8">
@{
var stats = new[]
{
new {
Label = "Lokasi Konservasi",
Value = @Model.Statistik.TotalLocations
},
new {
Label = "Jenis Flora",
Value = @Model.Statistik.TotalFlora
},
new {
Label = "Jenis Fauna",
Value = @Model.Statistik.TotalFauna
},
new {
Label = "Total Spesies",
Value = @Model.Statistik.TotalSpecies
}
};
}
@foreach (var item in stats)
{
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@item.Value
</div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
@item.Label
</div>
<div class="mx-auto grid max-w-7xl grid-cols-2 divide-x divide-border/60 px-4 sm:px-6 lg:grid-cols-4 lg:px-8">
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@ViewBag.TotalLokasi
</div>
}
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
Lokasi Konservasi
</div>
</div>
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@ViewBag.TotalTumbuhan
</div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
Jenis Flora
</div>
</div>
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@ViewBag.TotalFauna
</div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
Jenis Fauna
</div>
</div>
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@ViewBag.Total
</div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
Total Spesies
</div>
</div>
</div>
</section>
@ -141,7 +142,7 @@
Habitat di jantung Jakarta
</h2>
</div>
<a asp-controller="LokasiModel"
<a asp-controller="lokasi"
asp-action="Index"
class="hidden shrink-0 items-center gap-1.5 text-sm font-medium text-primary hover:underline sm:inline-flex">
Semua lokasi
@ -153,7 +154,7 @@
{
<a asp-controller="lokasi"
asp-action="detail"
asp-route-slug="@loc.Slug"
asp-route-slug="@Custom.Encode(loc.MsLokasiId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[16/10] overflow-hidden bg-muted">
@ -184,12 +185,12 @@
<span class="flex items-center gap-1">
<i data-lucide="leaf"
class="h-4 w-4 text-primary"></i>
12 Flora
@loc.LokasiTumbuhan.Count Flora
</span>
<span class="flex items-center gap-1">
<i data-lucide="bird"
class="h-4 w-4 text-primary"></i>
12 Fauna
@loc.LokasiFauna.Count Fauna
</span>
</div>
</div>
@ -224,7 +225,7 @@
{
<a asp-controller="flora"
asp-action="detail"
asp-route-slug="@s.Slug"
asp-route-slug="@Custom.Encode(s.MsTumbuhanId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
@ -236,15 +237,7 @@
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@* @if(s.Type == "Flora") *@
@* { *@
<i data-lucide="leaf" class="h-3 w-3"></i>
@* } *@
@* else *@
@* { *@
@* <i data-lucide="bird" class="h-3 w-3"></i> *@
@* } *@
@* @s.Cites *@
</div>
</div>
<!-- Content -->
@ -302,7 +295,7 @@
{
<a asp-controller="fauna"
asp-action="detail"
asp-route-slug="@s.Slug"
asp-route-slug="@Custom.Encode(s.MsFaunaId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
@ -313,16 +306,8 @@
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@* @if(s.Type == "Flora") *@
@* { *@
<i data-lucide="leaf" class="h-3 w-3"></i>
@* } *@
@* else *@
@* { *@
@* <i data-lucide="bird" class="h-3 w-3"></i> *@
@* } *@
@* @s.Cites *@
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
<i data-lucide="bird" class="h-3 w-3"></i>
</div>
</div>
<!-- Content -->

View File

@ -9,14 +9,11 @@
{ "Kritis", "bg-red-100 text-red-800 border-red-200" },
{ "Dilindungi", "bg-emerald-100 text-emerald-800 border-emerald-200" }
};
@model kehati.Models.View.HomeViewModel
var flora = Model.FeaturedSpesies.Where(x => x.Type == "flora").ToList();
var fauna = Model.FeaturedSpesies.Where(x => x.Type == "fauna").ToList();
}
<div>
<div class="relative h-[45vh] min-h-[320px] overflow-hidden">
<img src="~/images/@Model.Location.Image" asp-append-version="true" alt="@Model.Location.Name" class="h-full w-full object-cover"/>
<img src="~/images/@ViewBag.data.Image" asp-append-version="true" alt="@ViewBag.data.Name" class="h-full w-full object-cover"/>
<div class="absolute inset-0 bg-gradient-to-t from-background via-background/40 to-background/10"></div>
</div>
</div>
@ -30,25 +27,25 @@
Semua lokasi
</a>
<h1 class="mt-4 font-serif text-4xl leading-tight text-foreground sm:text-5xl">
@Model.Location.Name
@ViewBag.data.Name
</h1>
<div class="mt-4 flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground">
<span class="inline-flex items-center gap-1.5">
<i data-lucide="map-pin" class="h-4 w-4 text-primary"></i>
@Model.Location.Region
@ViewBag.data.Region
</span>
<span class="inline-flex items-center gap-1.5">
<i data-lucide="ruler" class="h-4 w-4 text-primary"></i>
@Model.Location.Area
@ViewBag.data.Area
</span>
</div>
<p class="mt-6 max-w-3xl text-base leading-relaxed text-muted-foreground">
@Model.Location.Description
Lorem ipsum dolor sit amet consectetur adipisicing elit. Maiores, praesentium at. Asperiores quasi explicabo, reiciendis ut nulla distinctio numquam labore dignissimos enim quisquam error et deleniti corrupti possimus nihil! Libero?
</p>
<div class="mt-6 flex gap-8 text-sm">
<div>
<div class="font-serif text-3xl text-primary">
@Model.Location.FloraCount
@ViewBag.lokasiTumbuhan.Count
</div>
<div class="text-xs uppercase tracking-widest text-muted-foreground">
Flora
@ -56,7 +53,7 @@
</div>
<div>
<div class="font-serif text-3xl text-primary">
@Model.Location.FaunaCount
@ViewBag.lokasiFauna.Count
</div>
<div class="text-xs uppercase tracking-widest text-muted-foreground">
Fauna
@ -69,116 +66,46 @@
<div class="mx-auto max-w-5xl px-4 py-16 sm:px-6 lg:px-8">
<div class="flex flex-wrap gap-3">
<button class="tab-btn active" data-tab="all">
Semua (@Model.FeaturedSpesies.Count)
<button class="tab-btn hover:cursor-pointer" data-tab="flora">
Flora (@ViewBag.lokasiTumbuhan.Count)
</button>
<button class="tab-btn" data-tab="flora">
Flora (@flora.Count)
</button>
<button class="tab-btn" data-tab="fauna">
Fauna (@fauna.Count)
<button class="tab-btn hover:cursor-pointer" data-tab="fauna">
Fauna (@ViewBag.lokasiFauna.Count)
</button>
</div>
<div id="tab-all" class="tab-content mt-8">
<div id="tab-flora" class="tab-content mt-8">
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
@foreach(SpesiesModel s in Model.FeaturedSpesies)
@foreach(var s in ViewBag.lokasiTumbuhan)
{
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image"
alt="@s.CommonName"
loading="lazy"
asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@if(s.Type == "Flora")
{
<i data-lucide="leaf" class="h-3 w-3"></i>
}
else
{
<i data-lucide="bird" class="h-3 w-3"></i>
}
@s.Type
</div>
</div>
<!-- Content -->
<div class="p-4">
<div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground">
@s.CommonName
</h3>
</div>
<p class="mt-0.5 text-xs italic text-muted-foreground">
@s.ScientificName
</p>
<!-- Status Badge -->
<div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.ConservationStatus)
? statusColor[s.ConservationStatus]
: "")">
@s.ConservationStatus
</span>
</div>
</div>
</a>
}
</div>
</div>
<div id="tab-flora" class="tab-content mt-8 hidden">
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
@foreach(var s in flora)
{
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Tumbuhan.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image"
alt="@s.CommonName"
<img src="~/images/@s.Tumbuhan.Image"
alt="@s.Tumbuhan.Name"
loading="lazy"
asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@if(s.Type == "Flora")
{
<i data-lucide="leaf" class="h-3 w-3"></i>
}
else
{
<i data-lucide="bird" class="h-3 w-3"></i>
}
@s.Type
</div>
</div>
<!-- Content -->
<div class="p-4">
<div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground">
@s.CommonName
@s.Tumbuhan.Name
</h3>
</div>
<p class="mt-0.5 text-xs italic text-muted-foreground">
@s.ScientificName
@s.Tumbuhan.NamaIlmiah
</p>
<!-- Status Badge -->
<div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.ConservationStatus)
? statusColor[s.ConservationStatus]
@(statusColor.ContainsKey(s.Tumbuhan.StatusPerlindungan)
? statusColor[s.Tumbuhan.StatusPerlindungan]
: "")">
@s.ConservationStatus
@s.Tumbuhan.StatusPerlindungan
</span>
</div>
</div>
@ -193,47 +120,39 @@
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
@foreach(SpesiesModel s in fauna)
@foreach(var s in ViewBag.lokasiFauna)
{
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Fauna.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image"
alt="@s.CommonName"
<img src="~/images/@s.Fauna.Image"
alt="@s.Fauna.Name"
loading="lazy"
asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@if(s.Type == "Flora")
{
<i data-lucide="leaf" class="h-3 w-3"></i>
}
else
{
<i data-lucide="bird" class="h-3 w-3"></i>
}
@s.Type
<i data-lucide="bird" class="h-3 w-3"></i> Fauna
</div>
</div>
<!-- Content -->
<div class="p-4">
<div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground">
@s.CommonName
@s.Fauna.Name
</h3>
</div>
<p class="mt-0.5 text-xs italic text-muted-foreground">
@s.ScientificName
@s.Fauna.NamaIlmiah
</p>
<!-- Status Badge -->
<div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.ConservationStatus)
? statusColor[s.ConservationStatus]
@(statusColor.ContainsKey(s.Fauna.Status)
? statusColor[s.Fauna.Status]
: "")">
@s.ConservationStatus
@s.Fauna.Status
</span>
</div>
</div>

View File

@ -1,6 +1,7 @@
@using kehati.Models.View
@using kehati.Models.Entity.Master
@using kehati.Models.Common
@using kehati.Helpers
@{
ViewData["Title"] = "Lokasi";
@ -27,7 +28,7 @@
{
<a asp-controller="lokasi"
asp-action="detail"
asp-route-slug="@loc.Slug"
asp-route-slug="@Custom.Encode(loc.MsLokasiId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[16/10] overflow-hidden bg-muted">
@ -58,12 +59,12 @@
<span class="flex items-center gap-1">
<i data-lucide="leaf"
class="h-4 w-4 text-primary"></i>
12 Flora
@loc.LokasiTumbuhan.Count Flora
</span>
<span class="flex items-center gap-1">
<i data-lucide="bird"
class="h-4 w-4 text-primary"></i>
13 Fauna
@loc.LokasiFauna.Count Fauna
</span>
</div>
</div>

View File

@ -1,52 +1,23 @@
@using kehati.Models.View
@using kehati.Helpers
@{
ViewData["Title"] = "Map";
}
<div class="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8">
<div class="max-w-2xl">
<div class="text-xs font-medium uppercase tracking-widest text-primary">
Peta Interaktif
</div>
<h1 class="mt-3 font-serif text-5xl leading-tight text-foreground">
Sebaran Lokasi Konservasi
</h1>
<p class="mt-4 text-lg text-muted-foreground">
Titik-titik hijau di peta Jakarta. Klik setiap penanda untuk melihat detail lokasi.
</p>
</div>
<!-- Leaflet -->
<div class="mt-10 overflow-hidden rounded-2xl border border-border shadow-sm">
<div id="map" class="h-[600px] w-full"></div>
</div>
<!-- Daftar Lokasi -->
<div class="mt-10 grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
@foreach(LokasiModel loc in Model.FeaturedLocations)
{
<div class="rounded-xl border border-border bg-card p-4">
<div class="font-serif text-lg text-foreground">
@loc.Name
</div>
<div class="mt-1 text-xs text-muted-foreground">
@loc.Region · @loc.FloraCount spesies terdokumentasi
</div>
</div>
}
</div>
</div>
@ -55,21 +26,42 @@
<script>
var map = L.map('map').setView([-6.2088,106.8456],11);
var customIcon = L.icon({
iconUrl: '/images/marker-icon.png',
iconRetinaUrl: '/images/marker-icon-2x.png',
shadowUrl: '/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution:'© OpenStreetMap'
}).addTo(map);
@foreach(LokasiModel l in Model.FeaturedLocations)
@foreach(var l in ViewBag.lokasiHome)
{
<text>
L.marker([@l.Latitude,@l.Longitude])
.addTo(map)
L.marker([@l.Lat,@l.Long],{
icon: customIcon
}).addTo(map)
.bindPopup(`
<strong>@l.Name - @l.Region</strong><br>
@l.FloraCount Flora terdokumentasi <br>
@l.FaunaCount Fauna terdokumentasi
<div style="font-size:11px!important;">
<strong>@l.Name</strong> <br />
Status Lokasi : @l.Status <br />
Flora : @l.LokasiTumbuhan.Count <br />
Fauna : @l.LokasiFauna.Count <br /><br />
@* <a class="" href="https://www.google.com/maps?q=@l.Lat,@l.Long" target="_blank"> *@
<a asp-controller="lokasi"
asp-action="detail"
asp-route-slug="@Custom.Encode(l.MsLokasiId)"
target="_blank">
Lihat Detail
</a>
</div>
`);
</text>

View File

@ -20,7 +20,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="~/css/leaflet.css" />
</head>
<body>
@{
@ -194,10 +194,18 @@
</li>
<li>
<a asp-controller="katalog"
<a asp-controller="flora"
asp-action="Index"
class="hover:text-foreground">
Katalog
Flora
</a>
</li>
<li>
<a asp-controller="fauna"
asp-action="Index"
class="hover:text-foreground">
Fauna
</a>
</li>
@ -249,8 +257,8 @@
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<script src="~/js/leaflet.js"></script>
<script src="~/js/lucide.js"></script>
<script>
const btn = document.getElementById('menuButton');
const menu = document.getElementById('mobileMenu');

View File

@ -8,75 +8,76 @@
}
<div class="mt-8">
<nav>
<ul class="pagination flex gap-1">
<nav>
<ul class="pagination flex gap-1">
@* Previous *@
@if (Model.HasPrevious)
{
<li class="p-3 border bg-white">
<a href="?page=@(current - 1)">
Previous
</a>
</li>
}
@* Halaman pertama *@
@if (start > 1)
{
<li class="p-3 border bg-white">
<a href="?page=1">1</a>
</li>
@if (start > 2)
@* Previous *@
@if (Model.HasPrevious)
{
<li class="p-3 border bg-white">
<span>...</span>
</li>
}
}
@* Halaman sekitar aktif *@
@for (int i = start; i <= end; i++)
{
<li class="page-item p-3 border rounded @(i == current ? "active bg-primary text-white" : "bg-white")">
<a href="?page=@i">
@i
</a>
</li>
}
@* Halaman terakhir *@
@if (end < total)
{
@if (end < total - 1)
{
<li class="p-3 border bg-white">
<span>...</span>
<a href="?page=@(current - 1)">
Previous
</a>
</li>
}
<li class="p-3 border bg-white">
<a href="?page=@total">
@total
</a>
</li>
}
@* Halaman pertama *@
@if (start > 1)
{
<li class="p-3 border bg-white">
<a href="?page=1">1</a>
</li>
@if (start > 2)
{
<li class="p-3 border bg-white">
<span>...</span>
</li>
}
}
@* Next *@
@if (Model.HasNext)
{
<li class="p-3 border bg-white">
<a href="?page=@(current + 1)">
Next
</a>
</li>
}
@* Halaman sekitar aktif *@
@for (int i = start; i <= end; i++)
{
<li class="page-item p-3 border rounded @(i == current ? "active bg-primary text-white" : "bg-white")">
</ul>
</nav>
<a href="?page=@i">
@i
</a>
</li>
}
@* Halaman terakhir *@
@if (end < total)
{
@if (end < total - 1)
{
<li class="p-3 border bg-white">
<span>...</span>
</li>
}
<li class="p-3 border bg-white">
<a href="?page=@total">
@total
</a>
</li>
}
@* Next *@
@if (Model.HasNext)
{
<li class="p-3 border bg-white">
<a href="?page=@(current + 1)">
Next
</a>
</li>
}
</ul>
</nav>
</div>

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("kehati")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6bc16bcdaded40520ae17144836179cbbb9ddf3b")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8c0968e5c63c2995ca864ca0475ff76c7cb0facc")]
[assembly: System.Reflection.AssemblyProductAttribute("kehati")]
[assembly: System.Reflection.AssemblyTitleAttribute("kehati")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
848d969054017e66ab06effc21957ea2250c3a56c687ec408f03a6b808daf569
287e6a2bd57b39a0597392f9bf6262b61772e83b7098c18d98c1399a76d6cc7e

View File

@ -1 +1 @@
3c47bf4ab7b38e3a0eb2f760261c7bb595133e0d70d143ddbd06f1d167e6b215
2aa414e5f0c16ea07a1df50d4b47ec5e8c134cd12f4762a9d39ad7bd1b4d8b0c

View File

@ -196,3 +196,6 @@
/Applications/MAMP/htdocs/kehati/bin/Debug/net9.0/zh-Hans/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll
/Applications/MAMP/htdocs/kehati/bin/Debug/net9.0/zh-Hant/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/y5cxcra3jr-6m5wzhvvn1.gz
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/zoo8rffbr6-i65bx55hda.gz
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/7h6jxd9k8n-47ih3oe4t7.gz
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/wkd5h07ok4-cf9mtx7t7r.gz

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
{"GlobalPropertiesHash":"hc8FL4d4SDyJq22ZKuiHZVVsIHQC48YE/mA5pBHYKc4=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"R7Rea/YQmcweqCbKffD9oUelggfpJQX85r65aYZsas0=","InputHashes":["Hhi2dhY28P3DU8GGefeY6F0yaYH0cMHiKCpVh33YhIU=","VOxc8xcqWt6gAM\u002BRuyfRLL1iQY9qPYh4n8cvKjwI3NY=","Sncp4ww/tjimD30ejpDv5D5eCiY\u002BGNCBHG31XvywcgE=","RSbekUJC7incuVtr7C0tXRzZN4BZamYDVsEZmrfQMcY=","0dj\u002B7dC25IeuLKXvwnTzfQVy\u002BUdHnl40sHhE/lKWrRI=","KPTC6joZ0rLn0eml9/Lsh6v1w6OotgKIxbWPkQPSc2U=","oc5dZJn7YA7RsQ0gtAnGAh7rgEphv3dYfFRixIhMKuU=","IBx1Zpi0iRpuwQy5fUr\u002B0BIjRN/f7k\u002BLtsRCoyIqdKg=","x60hTcC5q95RUcHEJci6kZJX\u002BOP5ZncNTZnLKMrK9TQ=","c4VjrF07youw\u002BkifvjAy7plxc6xm5/C/wcqlFxdrIoE=","MSox7E\u002BjIAaACE45MT\u002BrcCsRTWCQiB2IsO7d5a\u002BMvfY=","qTTBic4VK\u002B05MRJnLp9bSltvqEXfvU1zYGb2Yq\u002BZ1Pk=","NQukUql2iNTO4MQCyXa8T8bDU1wDElRnV\u002BBc2yCjEHg=","MgtQemV1N1h3/pFRW/IBNT4EgLJYsuxU0zbAcfbRCb4=","Goe41XQAQHCAcUIB4rTr07EWxMhW4VLC35VQ3i8zogk=","8bEfz8MdGCT\u002BUqVKCJhjT0KyMmRaMYgY/zLLZ1asfpE=","Ibz6Ix07csPbM7Pw2WcZZH0awAHeeZ0osg23I/UHwso=","icl4Xuqd3wVKdyQVGN6K0RJuiPUiZ1J3ZMQUAoAzfT0=","dweympdBNxv56b5xEWZUlkihih0FcF9WdEhWCjq2cXc=","fiFS/KvqSehFNqqcPmIkVbUMcMmBAjue0bCe3g32ZYs=","T3X1M\u002BUddK1SoFQOwNXuQKnudpv8ohop7rTlXDRkn4A=","QDGCJ/H0sJVm29CRqaE0VjtfDzWSx48qBmGqriGN89I=","WWNvV\u002BI7oSnu9ecmCS0Mck2eCGJvRs9a5UgkPxCOjRA=","Xc9BeHGukGDOMxRJ4DWKsD4Hl/eb6mEQZL6YmMBPRoY=","fOkK1386yU0SP0SXkMTynAZIbKu8kDOYliwg0q\u002BNskY=","oct6eD0w1zvUhMj0MXoNwhWFE2YjuoYqg3X96Ucuj4s=","67V7nn6u9b0acsh53M2HmglNpcktUtvOaw3gSRkwjx4=","ma1u/4RE/To974RJYUPGyGaqvCCeme6zJysx9w1ss3c=","o55JlXqf9P5uAQ2khL\u002B6zb9Tdmwm6I1og1gMy1YLpYY=","e0xtx5OOXKYFYOH5RifNbjh4spMMZ4OJe/5WIl23q7I=","5tm4FTjJTYh\u002BIfly7jRHNn4wSziZxSIN8wAEvIw\u002Bqjw=","BHdvCHnZlyS4zwSKcVy3ayvJezMLJXLcVN9R8deaH0g=","ntzaTVX8xBXsH995gvvXvmliXlCQotIsZXpZcglhOaE=","5kR/aL1DviNsyODfcczgmMzxSZCePCH9RPdTfI\u002BcgyA=","85jPWChWoCRZbXQRGb0iFqvZVPOqR7ev3FjdbkOn3N8=","Nbx2WCrP2GEddQzxS83sJa0zFj93vdmpK4GM2nty9uc=","QJPJj2QugL4XCdpHR\u002BUjqru7nIH7z/53/LJfz\u002B2u78E=","0OChFB9xM4RUbmHFnou7uAEh\u002BDlF54KM6B6j00g5Tmw=","ykyMr/QcfGzV063qPhl8tX3/1moBCOJG611QWUQ\u002BbHY=","/CLnWX/m7JPrsLGY\u002BXHRNWDTPsPKGvhpoUNMvUVySdk=","CkYBQvKkMzORePi8WPMM9aW2Lc3xVg5GJyDtKLXwYmY=","xwGlvpWqKnaz0RVaeRVxQ0PJMwOhvULJb3PN/FnF55I=","4xahvZCLorqqeX8Bk5JA9YF2zYf76VJFw\u002BFYV0Le/k0=","5SqPyjpm7H9Zc\u002BBbXBtZiOjmSi5f2cQeYLc7FuoB/ek=","0O4aVW29Vzt0B4Iet0T1oBGOM020UM\u002BLK2/yEbKH2dU=","HMwYA0Zexo0VNDlvtKgkk/e28ujKc1aNC91bm0MLMdk=","iNfcu84P3JCmFtqZp1chAvwyIZTOhH2RqhEneyvLrhs=","2hARyYn7NC4gbrlXbXtVzxaTHpcnwtUTyyjbnSGMmcs=","wHeoBQH8D12d4FpBCQgSAl7Y98J2wIbXVO87I4Oqnmo=","8cQHbaseDOOEdr82\u002B4L1dLbZfVOBGCzj7m1oStCM4RY=","8WGZEIW0hbJT1XkzSCtnaB50AHFRFH4MihnUs34mxhA=","3ZZyBE\u002BdA6aG7oGYzH8eisN1SphrAdQG8rxBn\u002BDzo/w=","BfFJRPyrADpgktkNNc2mfyFFZoBqauN9MCmAUWxe9Ug=","97Ja5zuGdMucJqedxH7CguZ\u002BiLSY4xYuyTXfJE/3mUs=","Gd2mz0U9mny2BKIeKQ\u002BRDt3csebXGOTHzvpBKmzTj9M=","ymiC674Nr\u002BpzpfZQAvz7VgMKWyqBem/OjSN8QeM3478=","tXqEhWxbNOqNYKJvB\u002B6TTsEx8KNlmzLfTndlyi8dcpg=","nYQ\u002BrXWj8wJ\u002BUt/T6U/wVc9UHvQjMUXDgcAtNNlnlcA=","qkZKbEyxkxbCDFtQ06Z9p3Fqpr6AUZHUiFlVpL00cJY=","mb/vdMDaE9L3J1vibUT8coaPWWPSUbGacfV5H5IP\u002BwU=","\u002BHDgqKS6Nqa5bRN/WtecsLITGr6T6whhbWPV0RjwQwM=","Gig3DQsXKloHGlDlRN26sGVUvT8\u002Bu50xYCWb/DK3fTE=","k5m16lGuQyO6e9aY4k1OYGzBolX0sixXAbsVhNDa7fQ=","MrFgmWKVAxban9XX2uqZQO23DWw0NGjsnWiIu9p11jo=","YQgUcWz2ue2oRWm0L9A\u002B\u002BDN/X2SNcdMG3yyz/5A0N4w=","XsOFFGStfZmGs4rkShh2uK3eN2ongLE0d9KBNjaXb6o=","7ITk8hLOO4uilCzXKB1iYKDtCVKMZ2vApR6K0z9qx0c=","RG4n1qULpz4qGNsyBiHJ1ebTfk9LKVz89pL0eSC8gPc=","4EfJtzv9kg3WWFzBqUt8CbF91bcAtW2ocJG4JUrULj8=","S2dH4yX4W/BjGC7Cp1Ov1rAVBSZJlC1sZbKwQRqMA4M=","krL8lBCCkIWVGoLQQThjIfoe6qs/xBAVnhPU3ywnuSs=","5Ad\u002Bef7REpth\u002B1aDMBr3B0HUtzchjmHZ69ipQ7F2ztQ=","0wADQAsURdwl9hsWFMFxN8u51iyhIefZ0\u002BfAdgRzQBM=","6omG1NdZNuYtZDubEy\u002BDST7\u002BfwfA5A3g2vDv80vluVI=","rRoeWHDFv91Dmdy9uNkQCarQ5nvPkifcZ5GBvZJDKDc=","4bsNytNaXkRk3ePwPIbWzq4IwszFAfZcWbCknkEszmA=","eLvoEvqRTPWrPYwFjRNV8D92N\u002BkvcZnoiJi9t9njyTo=","uoiinJcNOciOgqlO0GZQN2smtr6KoTAnah6dv5mVzek=","YoagLoMl49bUAbErIjNPzkNdCDgBDT514c90F9nGnfE=","uzjUeW\u002BKe/Mh7NhfiBvuinD0gzUKuynWF2VbhEIulVQ=","LdNXSSS5DEGYhs9mcjWxtU5uYD9N3kfGTAPRl6j6qWg=","g0y10m2DgfWcR\u002BBdcBNPC0hbivhMAc0z5cHhsqH1Tzc=","TgJ8XvI1vjoz8U9BMJ1maLQnqweAMT4a8ZSbLYUzoAE=","x8umpBTg0fvarcVhS22jEVXuAcL5hqCQF3JRc1qsxro=","s44dS6GzxTQjxM/Pb8o8DITAn8xEEod4rcdnoe\u002BHnjU=","6cZjyH6KHS45s38c7sN\u002BgpFF55ntUEhUWpNynNAafG8="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"hc8FL4d4SDyJq22ZKuiHZVVsIHQC48YE/mA5pBHYKc4=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"R7Rea/YQmcweqCbKffD9oUelggfpJQX85r65aYZsas0=","InputHashes":["Hhi2dhY28P3DU8GGefeY6F0yaYH0cMHiKCpVh33YhIU=","6cZjyH6KHS45s38c7sN\u002BgpFF55ntUEhUWpNynNAafG8=","VOxc8xcqWt6gAM\u002BRuyfRLL1iQY9qPYh4n8cvKjwI3NY=","Sncp4ww/tjimD30ejpDv5D5eCiY\u002BGNCBHG31XvywcgE=","RSbekUJC7incuVtr7C0tXRzZN4BZamYDVsEZmrfQMcY=","0dj\u002B7dC25IeuLKXvwnTzfQVy\u002BUdHnl40sHhE/lKWrRI=","KPTC6joZ0rLn0eml9/Lsh6v1w6OotgKIxbWPkQPSc2U=","oc5dZJn7YA7RsQ0gtAnGAh7rgEphv3dYfFRixIhMKuU=","IBx1Zpi0iRpuwQy5fUr\u002B0BIjRN/f7k\u002BLtsRCoyIqdKg=","x60hTcC5q95RUcHEJci6kZJX\u002BOP5ZncNTZnLKMrK9TQ=","c4VjrF07youw\u002BkifvjAy7plxc6xm5/C/wcqlFxdrIoE=","MSox7E\u002BjIAaACE45MT\u002BrcCsRTWCQiB2IsO7d5a\u002BMvfY=","qTTBic4VK\u002B05MRJnLp9bSltvqEXfvU1zYGb2Yq\u002BZ1Pk=","NQukUql2iNTO4MQCyXa8T8bDU1wDElRnV\u002BBc2yCjEHg=","MgtQemV1N1h3/pFRW/IBNT4EgLJYsuxU0zbAcfbRCb4=","Goe41XQAQHCAcUIB4rTr07EWxMhW4VLC35VQ3i8zogk=","8bEfz8MdGCT\u002BUqVKCJhjT0KyMmRaMYgY/zLLZ1asfpE=","Ibz6Ix07csPbM7Pw2WcZZH0awAHeeZ0osg23I/UHwso=","icl4Xuqd3wVKdyQVGN6K0RJuiPUiZ1J3ZMQUAoAzfT0=","dweympdBNxv56b5xEWZUlkihih0FcF9WdEhWCjq2cXc=","fiFS/KvqSehFNqqcPmIkVbUMcMmBAjue0bCe3g32ZYs=","T3X1M\u002BUddK1SoFQOwNXuQKnudpv8ohop7rTlXDRkn4A=","QDGCJ/H0sJVm29CRqaE0VjtfDzWSx48qBmGqriGN89I=","WWNvV\u002BI7oSnu9ecmCS0Mck2eCGJvRs9a5UgkPxCOjRA=","Xc9BeHGukGDOMxRJ4DWKsD4Hl/eb6mEQZL6YmMBPRoY=","fOkK1386yU0SP0SXkMTynAZIbKu8kDOYliwg0q\u002BNskY=","oct6eD0w1zvUhMj0MXoNwhWFE2YjuoYqg3X96Ucuj4s=","67V7nn6u9b0acsh53M2HmglNpcktUtvOaw3gSRkwjx4=","ma1u/4RE/To974RJYUPGyGaqvCCeme6zJysx9w1ss3c=","o55JlXqf9P5uAQ2khL\u002B6zb9Tdmwm6I1og1gMy1YLpYY=","e0xtx5OOXKYFYOH5RifNbjh4spMMZ4OJe/5WIl23q7I=","5tm4FTjJTYh\u002BIfly7jRHNn4wSziZxSIN8wAEvIw\u002Bqjw=","BHdvCHnZlyS4zwSKcVy3ayvJezMLJXLcVN9R8deaH0g=","ntzaTVX8xBXsH995gvvXvmliXlCQotIsZXpZcglhOaE=","5kR/aL1DviNsyODfcczgmMzxSZCePCH9RPdTfI\u002BcgyA=","85jPWChWoCRZbXQRGb0iFqvZVPOqR7ev3FjdbkOn3N8=","Nbx2WCrP2GEddQzxS83sJa0zFj93vdmpK4GM2nty9uc=","QJPJj2QugL4XCdpHR\u002BUjqru7nIH7z/53/LJfz\u002B2u78E=","0OChFB9xM4RUbmHFnou7uAEh\u002BDlF54KM6B6j00g5Tmw=","ykyMr/QcfGzV063qPhl8tX3/1moBCOJG611QWUQ\u002BbHY=","/CLnWX/m7JPrsLGY\u002BXHRNWDTPsPKGvhpoUNMvUVySdk=","CkYBQvKkMzORePi8WPMM9aW2Lc3xVg5GJyDtKLXwYmY=","xwGlvpWqKnaz0RVaeRVxQ0PJMwOhvULJb3PN/FnF55I=","4xahvZCLorqqeX8Bk5JA9YF2zYf76VJFw\u002BFYV0Le/k0=","5SqPyjpm7H9Zc\u002BBbXBtZiOjmSi5f2cQeYLc7FuoB/ek=","0O4aVW29Vzt0B4Iet0T1oBGOM020UM\u002BLK2/yEbKH2dU=","HMwYA0Zexo0VNDlvtKgkk/e28ujKc1aNC91bm0MLMdk=","iNfcu84P3JCmFtqZp1chAvwyIZTOhH2RqhEneyvLrhs=","2hARyYn7NC4gbrlXbXtVzxaTHpcnwtUTyyjbnSGMmcs=","wHeoBQH8D12d4FpBCQgSAl7Y98J2wIbXVO87I4Oqnmo=","8cQHbaseDOOEdr82\u002B4L1dLbZfVOBGCzj7m1oStCM4RY=","8WGZEIW0hbJT1XkzSCtnaB50AHFRFH4MihnUs34mxhA=","3ZZyBE\u002BdA6aG7oGYzH8eisN1SphrAdQG8rxBn\u002BDzo/w=","BfFJRPyrADpgktkNNc2mfyFFZoBqauN9MCmAUWxe9Ug=","97Ja5zuGdMucJqedxH7CguZ\u002BiLSY4xYuyTXfJE/3mUs=","Gd2mz0U9mny2BKIeKQ\u002BRDt3csebXGOTHzvpBKmzTj9M=","ymiC674Nr\u002BpzpfZQAvz7VgMKWyqBem/OjSN8QeM3478=","tXqEhWxbNOqNYKJvB\u002B6TTsEx8KNlmzLfTndlyi8dcpg=","nYQ\u002BrXWj8wJ\u002BUt/T6U/wVc9UHvQjMUXDgcAtNNlnlcA=","qkZKbEyxkxbCDFtQ06Z9p3Fqpr6AUZHUiFlVpL00cJY=","mb/vdMDaE9L3J1vibUT8coaPWWPSUbGacfV5H5IP\u002BwU=","\u002BHDgqKS6Nqa5bRN/WtecsLITGr6T6whhbWPV0RjwQwM=","Gig3DQsXKloHGlDlRN26sGVUvT8\u002Bu50xYCWb/DK3fTE=","k5m16lGuQyO6e9aY4k1OYGzBolX0sixXAbsVhNDa7fQ=","MrFgmWKVAxban9XX2uqZQO23DWw0NGjsnWiIu9p11jo=","YQgUcWz2ue2oRWm0L9A\u002B\u002BDN/X2SNcdMG3yyz/5A0N4w=","XsOFFGStfZmGs4rkShh2uK3eN2ongLE0d9KBNjaXb6o=","7ITk8hLOO4uilCzXKB1iYKDtCVKMZ2vApR6K0z9qx0c=","RG4n1qULpz4qGNsyBiHJ1ebTfk9LKVz89pL0eSC8gPc=","4EfJtzv9kg3WWFzBqUt8CbF91bcAtW2ocJG4JUrULj8=","S2dH4yX4W/BjGC7Cp1Ov1rAVBSZJlC1sZbKwQRqMA4M=","krL8lBCCkIWVGoLQQThjIfoe6qs/xBAVnhPU3ywnuSs=","5Ad\u002Bef7REpth\u002B1aDMBr3B0HUtzchjmHZ69ipQ7F2ztQ=","0wADQAsURdwl9hsWFMFxN8u51iyhIefZ0\u002BfAdgRzQBM=","6omG1NdZNuYtZDubEy\u002BDST7\u002BfwfA5A3g2vDv80vluVI=","rRoeWHDFv91Dmdy9uNkQCarQ5nvPkifcZ5GBvZJDKDc=","4bsNytNaXkRk3ePwPIbWzq4IwszFAfZcWbCknkEszmA=","eLvoEvqRTPWrPYwFjRNV8D92N\u002BkvcZnoiJi9t9njyTo=","uoiinJcNOciOgqlO0GZQN2smtr6KoTAnah6dv5mVzek=","YoagLoMl49bUAbErIjNPzkNdCDgBDT514c90F9nGnfE=","uzjUeW\u002BKe/Mh7NhfiBvuinD0gzUKuynWF2VbhEIulVQ=","LdNXSSS5DEGYhs9mcjWxtU5uYD9N3kfGTAPRl6j6qWg=","g0y10m2DgfWcR\u002BBdcBNPC0hbivhMAc0z5cHhsqH1Tzc=","TgJ8XvI1vjoz8U9BMJ1maLQnqweAMT4a8ZSbLYUzoAE=","x8umpBTg0fvarcVhS22jEVXuAcL5hqCQF3JRc1qsxro=","s44dS6GzxTQjxM/Pb8o8DITAn8xEEod4rcdnoe\u002BHnjU=","5RyDkb5bkMHF3rqO8otxasIMg5/zCbCdvUJsmz3WVaU=","Q5qUvHyXoamo\u002BgYNAPmQ84\u002Bf8tkj8iVuJAELR9S94yM=","ieXygR5v0xhQOkugvDpC/J6UgBI\u002BJr8PduZ64tbabJo="],"CachedAssets":{},"CachedCopyCandidates":{}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
zroMRd2dcHXmYm65YWxO2Mn745dIiqwuztzw31lUAPU=
Sceb8JetqiKI7u2xWWtnJLy4d7Cutkf8tE9PARSX2mk=

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,664 @@
/* required styles */
.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
image-rendering: -webkit-optimize-contrast;
}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
width: 1600px;
height: 1600px;
-webkit-transform-origin: 0 0;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg {
max-width: none !important;
max-height: none !important;
}
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
max-width: none !important;
max-height: none !important;
width: auto;
padding: 0;
}
.leaflet-container img.leaflet-tile {
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
mix-blend-mode: plus-lighter;
}
.leaflet-container.leaflet-touch-zoom {
-ms-touch-action: pan-x pan-y;
touch-action: pan-x pan-y;
}
.leaflet-container.leaflet-touch-drag {
-ms-touch-action: pinch-zoom;
/* Fallback for FF which doesn't support pinch-zoom */
touch-action: none;
touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
-ms-touch-action: none;
touch-action: none;
}
.leaflet-container {
-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
z-index: 800;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-pane { z-index: 400; }
.leaflet-tile-pane { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane { z-index: 500; }
.leaflet-marker-pane { z-index: 600; }
.leaflet-tooltip-pane { z-index: 650; }
.leaflet-popup-pane { z-index: 700; }
.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg { z-index: 200; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 800;
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-animated {
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
}
svg.leaflet-zoom-animated {
will-change: transform;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
-webkit-transition: none;
-moz-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-interactive {
cursor: pointer;
}
.leaflet-grab {
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab;
}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
cursor: crosshair;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
cursor: grabbing;
}
/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
pointer-events: none;
}
.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline-offset: 1px;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
font-size: 12px;
font-size: 0.75rem;
line-height: 1.5;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover,
.leaflet-bar a:focus {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
.leaflet-touch .leaflet-bar a:first-child {
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.leaflet-touch .leaflet-bar a:last-child {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
font-size: 22px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-scrollbar {
overflow-y: scroll;
overflow-x: hidden;
padding-right: 5px;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
font-size: 13px;
font-size: 1.08333em;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* Default icon URLs */
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
background-image: url(images/marker-icon.png);
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.8);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
line-height: 1.4;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover,
.leaflet-control-attribution a:focus {
text-decoration: underline;
}
.leaflet-attribution-flag {
display: inline !important;
vertical-align: baseline !important;
width: 1em;
height: 0.6669em;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
white-space: nowrap;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: rgba(255, 255, 255, 0.8);
text-shadow: 1px 1px #fff;
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
margin-bottom: 20px;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 24px 13px 20px;
line-height: 1.3;
font-size: 13px;
font-size: 1.08333em;
min-height: 1px;
}
.leaflet-popup-content p {
margin: 17px 0;
margin: 1.3em 0;
}
.leaflet-popup-tip-container {
width: 40px;
height: 20px;
position: absolute;
left: 50%;
margin-top: -1px;
margin-left: -20px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
pointer-events: auto;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
color: #333;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
border: none;
text-align: center;
width: 24px;
height: 24px;
font: 16px/24px Tahoma, Verdana, sans-serif;
color: #757575;
text-decoration: none;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover,
.leaflet-container a.leaflet-popup-close-button:focus {
color: #585858;
}
.leaflet-popup-scrolled {
overflow: auto;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
-ms-zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
position: absolute;
padding: 6px;
background-color: #fff;
border: 1px solid #fff;
border-radius: 3px;
color: #222;
white-space: nowrap;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
.leaflet-tooltip.leaflet-interactive {
cursor: pointer;
pointer-events: auto;
}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
position: absolute;
pointer-events: none;
border: 6px solid transparent;
background: transparent;
content: "";
}
/* Directions */
.leaflet-tooltip-bottom {
margin-top: 6px;
}
.leaflet-tooltip-top {
margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
left: 50%;
margin-left: -6px;
}
.leaflet-tooltip-top:before {
bottom: 0;
margin-bottom: -12px;
border-top-color: #fff;
}
.leaflet-tooltip-bottom:before {
top: 0;
margin-top: -12px;
margin-left: -6px;
border-bottom-color: #fff;
}
.leaflet-tooltip-left {
margin-left: -6px;
}
.leaflet-tooltip-right {
margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
top: 50%;
margin-top: -6px;
}
.leaflet-tooltip-left:before {
right: 0;
margin-right: -12px;
border-left-color: #fff;
}
.leaflet-tooltip-right:before {
left: 0;
margin-left: -12px;
border-right-color: #fff;
}
/* Printing */
@media print {
/* Prevent printers from removing background-images of controls. */
.leaflet-control {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long