Compare commits
2 Commits
d90123a56d
...
7e6b369b48
Author | SHA1 | Date | |
---|---|---|---|
7e6b369b48 | |||
362a8784ba |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
appsettings.json
|
appsettings.json
|
||||||
|
assets/exchangepairs.json
|
||||||
|
|
||||||
# ---> VisualStudio
|
# ---> VisualStudio
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
22
Conversion/ConversionConfig.cs
Normal file
22
Conversion/ConversionConfig.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace silverworker_discord.Conversion
|
||||||
|
{
|
||||||
|
public class ConversionConfig
|
||||||
|
{
|
||||||
|
public class KnownUnit
|
||||||
|
{
|
||||||
|
public string Canonical { get; set; }
|
||||||
|
public IEnumerable<string> Aliases { get; set; }
|
||||||
|
}
|
||||||
|
public class LinearPair
|
||||||
|
{
|
||||||
|
public string item1 { get; set; }
|
||||||
|
public string item2 { get; set; }
|
||||||
|
public decimal factor { get; set; }
|
||||||
|
}
|
||||||
|
public IEnumerable<KnownUnit> Units { get; set; }
|
||||||
|
public IEnumerable<LinearPair> LinearPairs { get; set; }
|
||||||
|
}
|
||||||
|
}
|
186
Conversion/Converter.cs
Normal file
186
Conversion/Converter.cs
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using QRCoder;
|
||||||
|
|
||||||
|
namespace silverworker_discord.Conversion
|
||||||
|
{
|
||||||
|
public static class Converter
|
||||||
|
{
|
||||||
|
|
||||||
|
private delegate decimal Convert1Way(decimal input);
|
||||||
|
private static string currencyPath;
|
||||||
|
private static ExchangePairs currencyConf = null;
|
||||||
|
private static DateTime lastUpdatedCurrency = DateTime.UnixEpoch;
|
||||||
|
private static List<Tuple<string, string, Convert1Way, Convert1Way>> knownConversions = new List<Tuple<string, string, Convert1Way, Convert1Way>>()
|
||||||
|
{
|
||||||
|
new Tuple<string, string, Convert1Way, Convert1Way>("℉", "°C", (f => {return(f- 32.0m) / 1.8m;}), (c => {return 1.8m*c + 32.0m;})),
|
||||||
|
};
|
||||||
|
private static Dictionary<List<string>, string> knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>());
|
||||||
|
|
||||||
|
public static string convert(string message)
|
||||||
|
{
|
||||||
|
var theseMatches = Regex.Matches(message, "\\b([\\d]+\\.?\\d*) ?([^\\d\\s].*) (in|to|as) ([^\\d\\s].*)$", RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
if (theseMatches != null && theseMatches.Count > 0 && theseMatches[0].Groups != null && theseMatches[0].Groups.Count == 5)
|
||||||
|
{
|
||||||
|
decimal asNumeric = 0;
|
||||||
|
if (decimal.TryParse(theseMatches[0].Groups[1].Value, out asNumeric))
|
||||||
|
{
|
||||||
|
return actualConvert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower());
|
||||||
|
}
|
||||||
|
return "mysteriously semi-parsable";
|
||||||
|
}
|
||||||
|
return "unparsable";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Load(string currencyPath)
|
||||||
|
{
|
||||||
|
Converter.currencyPath = currencyPath;
|
||||||
|
var convConf = JsonConvert.DeserializeObject<ConversionConfig>(File.ReadAllText("assets/conversion.json"));
|
||||||
|
foreach (var unit in convConf.Units)
|
||||||
|
{
|
||||||
|
knownAliases.Add(unit.Aliases.ToList(), unit.Canonical);
|
||||||
|
}
|
||||||
|
foreach (var lp in convConf.LinearPairs)
|
||||||
|
{
|
||||||
|
AddLinearPair(lp.item1, lp.item2, lp.factor);
|
||||||
|
}
|
||||||
|
Task.Run(async () => {
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
loadCurrency();
|
||||||
|
await Task.Delay(TimeSpan.FromHours(8));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private static void loadCurrency()
|
||||||
|
{
|
||||||
|
Console.WriteLine("loading currency exchange data.");
|
||||||
|
if (File.Exists(currencyPath))
|
||||||
|
{
|
||||||
|
currencyConf = JsonConvert.DeserializeObject<ExchangePairs>(File.ReadAllText(currencyPath));
|
||||||
|
|
||||||
|
knownAliases.Add(new List<string>() { currencyConf.Base.ToLower() }, currencyConf.Base);
|
||||||
|
foreach (var rate in currencyConf.rates)
|
||||||
|
{
|
||||||
|
knownAliases.Add(new List<string>() { rate.Key.ToLower() }, rate.Key);
|
||||||
|
AddLinearPair(currencyConf.Base, rate.Key, rate.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string actualConvert(decimal numericTerm, string sourceunit, string destinationUnit)
|
||||||
|
{
|
||||||
|
var normalizedSourceUnit = normalizeUnit(sourceunit);
|
||||||
|
if (string.IsNullOrWhiteSpace(normalizedSourceUnit))
|
||||||
|
{
|
||||||
|
return $"what's {sourceunit}?";
|
||||||
|
}
|
||||||
|
var normalizedDestUnit = normalizeUnit(destinationUnit);
|
||||||
|
if (string.IsNullOrWhiteSpace(normalizedDestUnit))
|
||||||
|
{
|
||||||
|
return $"what's {destinationUnit}?";
|
||||||
|
}
|
||||||
|
if (normalizedSourceUnit == normalizedDestUnit)
|
||||||
|
{
|
||||||
|
return $"source and dest are the same, so... {numericTerm} {normalizedDestUnit}?";
|
||||||
|
}
|
||||||
|
var foundPath = exhaustiveBreadthFirst(normalizedDestUnit, new List<string>() { normalizedSourceUnit })?.ToList();
|
||||||
|
|
||||||
|
if (foundPath != null)
|
||||||
|
{
|
||||||
|
var accumulator = numericTerm;
|
||||||
|
for (int j = 0; j < foundPath.Count - 1; j++)
|
||||||
|
{
|
||||||
|
var forwardConversion = knownConversions.FirstOrDefault(kc => kc.Item1 == foundPath[j] && kc.Item2 == foundPath[j + 1]);
|
||||||
|
if (forwardConversion != null)
|
||||||
|
{
|
||||||
|
accumulator = forwardConversion.Item3(accumulator);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var reverseConversion = knownConversions.First(kc => kc.Item2 == foundPath[j] && kc.Item1 == foundPath[j + 1]);
|
||||||
|
accumulator = reverseConversion.Item4(accumulator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (normalizedDestUnit == currencyConf.Base || currencyConf.rates.Select(r => r.Key).Contains(normalizedDestUnit))
|
||||||
|
{
|
||||||
|
return $"{String.Format("approximately {0:0.00}", accumulator)} {normalizedDestUnit} as of {currencyConf.DateUpdated.ToLongDateString()}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $"{String.Format("{0:G4}", accumulator)} {normalizedDestUnit}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "no conversion known";
|
||||||
|
}
|
||||||
|
private static string normalizeUnit(string unit)
|
||||||
|
{
|
||||||
|
var normalizedUnit = unit.ToLower();
|
||||||
|
if (normalizedUnit.EndsWith("es"))
|
||||||
|
{
|
||||||
|
normalizedUnit = normalizedUnit.Substring(0, normalizedUnit.Length - 2);
|
||||||
|
}
|
||||||
|
else if (normalizedUnit.EndsWith('s'))
|
||||||
|
{
|
||||||
|
normalizedUnit = normalizedUnit.Substring(0, normalizedUnit.Length - 1);
|
||||||
|
}
|
||||||
|
if (knownConversions.FirstOrDefault(c => c.Item1 == normalizedUnit || c.Item2 == normalizedUnit) != null)
|
||||||
|
{
|
||||||
|
return normalizedUnit;
|
||||||
|
}
|
||||||
|
if (!knownAliases.ContainsValue(normalizedUnit))
|
||||||
|
{
|
||||||
|
var key = knownAliases.Keys.FirstOrDefault(listkey => listkey.Contains(normalizedUnit));
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
return knownAliases[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private static IEnumerable<string> exhaustiveBreadthFirst(string dest, IEnumerable<string> currentPath)
|
||||||
|
{
|
||||||
|
var last = currentPath.Last();
|
||||||
|
if (last == dest)
|
||||||
|
{
|
||||||
|
return currentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
var toTest = new List<List<string>>();
|
||||||
|
foreach (var conv in knownConversions)
|
||||||
|
{
|
||||||
|
if (conv.Item1 == last && currentPath.Contains(conv.Item2) == false && conv.Item3 != null)
|
||||||
|
{
|
||||||
|
var test = exhaustiveBreadthFirst(dest, currentPath.Append(conv.Item2));
|
||||||
|
if (test != null)
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
if (conv.Item2 == last && currentPath.Contains(conv.Item1) == false && conv.Item4 != null)
|
||||||
|
{
|
||||||
|
var test = exhaustiveBreadthFirst(dest, currentPath.Append(conv.Item1));
|
||||||
|
if (test != null)
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private static void AddLinearPair(string key1, string key2, decimal factor)
|
||||||
|
{
|
||||||
|
var reverseFactor = 1.0m / factor;
|
||||||
|
knownConversions.Add(new Tuple<string, string, Convert1Way, Convert1Way>(
|
||||||
|
key1, key2, x => x * factor, y => y * reverseFactor
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
Conversion/ExchangePairs.cs
Normal file
15
Conversion/ExchangePairs.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace silverworker_discord.Conversion
|
||||||
|
{
|
||||||
|
public class ExchangePairs
|
||||||
|
{
|
||||||
|
public string disclaimer{ get; set; }
|
||||||
|
public string license{ get; set; }
|
||||||
|
public int timestamp{ get; set; }
|
||||||
|
public DateTime DateUpdated { get { return DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime(); }}
|
||||||
|
public string Base{ get; set; }
|
||||||
|
public Dictionary<string, decimal> rates { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -151,6 +152,10 @@ namespace silverworker_discord
|
|||||||
Console.Error.WriteLine($"convert failed :( qr{todaysnumber}");
|
Console.Error.WriteLine($"convert failed :( qr{todaysnumber}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static async void Convert(SocketUserMessage message)
|
||||||
|
{
|
||||||
|
await message.Channel.SendMessageAsync(Conversion.Converter.convert(message.Content));
|
||||||
|
}
|
||||||
public static async void Joke(SocketUserMessage message)
|
public static async void Joke(SocketUserMessage message)
|
||||||
{
|
{
|
||||||
var jokes = File.ReadAllLines("assets/jokes.txt");
|
var jokes = File.ReadAllLines("assets/jokes.txt");
|
||||||
|
@ -47,6 +47,7 @@ namespace silverworker_discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Conversion.Converter.Load(config["exchangePairsLocation"]);
|
||||||
|
|
||||||
_client = new DiscordSocketClient();
|
_client = new DiscordSocketClient();
|
||||||
|
|
||||||
@ -200,6 +201,10 @@ namespace silverworker_discord
|
|||||||
{
|
{
|
||||||
//Features.countdown(msgText.Substring("!countdown ".Length + msgText.IndexOf("!countdown ")), message); //converting human readable times is hard :/
|
//Features.countdown(msgText.Substring("!countdown ".Length + msgText.IndexOf("!countdown ")), message); //converting human readable times is hard :/
|
||||||
}
|
}
|
||||||
|
if (msgText.Contains("!freedomunits "))
|
||||||
|
{
|
||||||
|
Features.Convert(message);
|
||||||
|
}
|
||||||
if (Regex.IsMatch(msgText, "!joke\\b"))
|
if (Regex.IsMatch(msgText, "!joke\\b"))
|
||||||
{
|
{
|
||||||
Features.Joke(message);
|
Features.Joke(message);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"token": "59 chars"
|
"token": "59 chars",
|
||||||
|
"exchangePairsLocation": "assets/exchangepairs.json"
|
||||||
}
|
}
|
257
assets/conversion.json
Normal file
257
assets/conversion.json
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
{
|
||||||
|
"units":[
|
||||||
|
{
|
||||||
|
"canonical": "℉",
|
||||||
|
"aliases": [
|
||||||
|
"degrees f",
|
||||||
|
"deg f",
|
||||||
|
"degf",
|
||||||
|
"fahrenheit",
|
||||||
|
"deg fahrenheit",
|
||||||
|
"degrees fahrenheit",
|
||||||
|
"°f",
|
||||||
|
"° f",
|
||||||
|
"℉",
|
||||||
|
"f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"°C",
|
||||||
|
"aliases": [
|
||||||
|
"degrees c",
|
||||||
|
"deg c",
|
||||||
|
"degc",
|
||||||
|
"celsius",
|
||||||
|
"deg celsiu",
|
||||||
|
"degrees celsiu",
|
||||||
|
"°c",
|
||||||
|
"° c",
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"m",
|
||||||
|
"aliases": [
|
||||||
|
"meter",
|
||||||
|
"metre"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"km",
|
||||||
|
"aliases": [
|
||||||
|
"kilometer",
|
||||||
|
"kilometre"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"kg",
|
||||||
|
"aliases": [
|
||||||
|
"kilogram",
|
||||||
|
"kilo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"g",
|
||||||
|
"aliases": [
|
||||||
|
"gram"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"lb",
|
||||||
|
"aliases": [
|
||||||
|
"pound"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"oz",
|
||||||
|
"aliases": [
|
||||||
|
"ounce"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"floz",
|
||||||
|
"aliases": [
|
||||||
|
"us fl oz",
|
||||||
|
"us fl ounce",
|
||||||
|
"us fluid ounce",
|
||||||
|
"us fluid oz"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"mL",
|
||||||
|
"aliases": [
|
||||||
|
"ml",
|
||||||
|
"milliletre",
|
||||||
|
"millileter"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"ft",
|
||||||
|
"aliases": [
|
||||||
|
"'",
|
||||||
|
"feet",
|
||||||
|
"foot"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"in",
|
||||||
|
"aliases": [
|
||||||
|
"\"",
|
||||||
|
"inch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"yd",
|
||||||
|
"aliases": [
|
||||||
|
"yard"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"hhd",
|
||||||
|
"aliases": [
|
||||||
|
"hogshead"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"gal",
|
||||||
|
"aliases": [
|
||||||
|
"gallon"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"tbsp",
|
||||||
|
"aliases": [
|
||||||
|
"tablespoon",
|
||||||
|
"table spoon"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"tsp",
|
||||||
|
"aliases": [
|
||||||
|
"teaspoon",
|
||||||
|
"tea spoon"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"qt",
|
||||||
|
"aliases": [
|
||||||
|
"quart"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"ac",
|
||||||
|
"aliases": [
|
||||||
|
"acres"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"AU",
|
||||||
|
"aliases": [
|
||||||
|
"au",
|
||||||
|
"astronomical unit"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"Pa",
|
||||||
|
"aliases": [
|
||||||
|
"pascal",
|
||||||
|
"pa"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"kPa",
|
||||||
|
"aliases": [
|
||||||
|
"kilopascal",
|
||||||
|
"kpa"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"atm",
|
||||||
|
"aliases": [
|
||||||
|
"atmosphere"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"m^2",
|
||||||
|
"aliases": [
|
||||||
|
"square meter",
|
||||||
|
"meter squared",
|
||||||
|
"meters squared",
|
||||||
|
"sq meter",
|
||||||
|
"sq m",
|
||||||
|
"sqm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"km^2",
|
||||||
|
"aliases": [
|
||||||
|
"square kilometer",
|
||||||
|
"kilometer squared",
|
||||||
|
"kilometers squared",
|
||||||
|
"sq kilometer",
|
||||||
|
"sq km",
|
||||||
|
"sqkm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"ly",
|
||||||
|
"aliases": [
|
||||||
|
"light year"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"canonical":"pc",
|
||||||
|
"aliases": [
|
||||||
|
"parsec"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"linearPairs":[
|
||||||
|
{"item1":"kg", "item2":"g", "factor":1000},
|
||||||
|
{"item1":"lb", "item2":"oz", "factor":16},
|
||||||
|
{"item1":"kg", "item2":"lb", "factor":2.204623},
|
||||||
|
|
||||||
|
{"item1":"km", "item2":"m", "factor":1000},
|
||||||
|
{"item1":"mi", "item2":"ft", "factor":5280},
|
||||||
|
{"item1":"m", "item2":"in", "factor":39.37008},
|
||||||
|
{"item1":"m", "item2":"cm", "factor":100},
|
||||||
|
{"item1":"km", "item2":"mi", "factor":0.6213712},
|
||||||
|
{"item1":"ft", "item2":"in", "factor":12},
|
||||||
|
{"item1":"yd", "item2":"ft", "factor":3},
|
||||||
|
{"item1":"chain", "item2":"yd", "factor":22},
|
||||||
|
{"item1":"chain", "item2":"link", "factor":100},
|
||||||
|
{"item1":"furlong", "item2":"mi", "factor":8},
|
||||||
|
{"item1":"rod", "item2":"ft", "factor":16.5},
|
||||||
|
{"item1":"AU", "item2":"ly", "factor": 0.0000158125},
|
||||||
|
{"item1":"ly", "item2":"km", "factor": 946070000000},
|
||||||
|
{"item1":"pc", "item2":"AU", "factor":206266.3},
|
||||||
|
|
||||||
|
{"item1":"floz", "item2":"mL", "factor":29.57344},
|
||||||
|
{"item1":"L", "item2":"mL", "factor":1000},
|
||||||
|
{"item1":"L", "item2":"floz", "factor":33.81402},
|
||||||
|
{"item1":"hhd", "item2":"gal", "factor":54},
|
||||||
|
{"item1":"barrel", "item2":"kilderkin", "factor":2},
|
||||||
|
{"item1":"barrel", "item2":"firkin", "factor":4},
|
||||||
|
{"item1":"pint", "item2":"floz", "factor":16},
|
||||||
|
{"item1":"cup", "item2":"floz", "factor":8},
|
||||||
|
{"item1":"gill", "item2":"floz", "factor":4},
|
||||||
|
{"item1":"tbsp", "item2":"tsp", "factor":3},
|
||||||
|
{"item1":"tbsp", "item2":"floz", "factor":0.5},
|
||||||
|
{"item1":"gal", "item2":"floz", "factor":128},
|
||||||
|
{"item1":"gal", "item2":"qt", "factor":4},
|
||||||
|
|
||||||
|
|
||||||
|
{"item1":"acre", "item2":"yd^2", "factor":4840},
|
||||||
|
{"item1":"yd^2", "item2":"m^2", "factor":0.836127},
|
||||||
|
|
||||||
|
{"item1":"mph", "item2":"knot", "factor":0.868976},
|
||||||
|
{"item1":"mph", "item2":"kph", "factor":1.609343550606653},
|
||||||
|
|
||||||
|
|
||||||
|
{"item1":"kPa", "item2":"Pa", "factor":1000},
|
||||||
|
{"item1":"Nm^2", "item2":"Pa", "factor":1},
|
||||||
|
{"item1":"Pa", "item2":"bar", "factor":100},
|
||||||
|
{"item1":"atm", "item2":"Pa", "factor":101325},
|
||||||
|
{"item1":"bar", "item2":"psi", "factor":14.5038}
|
||||||
|
]
|
||||||
|
}
|
@ -16,14 +16,17 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="AppSettings.json">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="assets/jokes.txt">
|
<None Update="assets/jokes.txt">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="assets/coding and algorithms.png">
|
<None Update="assets/coding and algorithms.png">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="assets/ekgblip.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
Reference in New Issue
Block a user