19,785 Matching Annotations
  1. Jan 2022
    1. I'm not sure what behaviour it is that you expect. "$; foo = bar.a" means that you expect foo to always be whatever bar.a is, and "bind:value={foo}" means that you expect foo to to be whatever has been entered in the input. It can't be both!
    1. having inconsistencies when all the "subtle" conditions were met is unfriendly. it requires the user to have much deeper understanding of the nuances of the language.
    2. I used the word "intended" behavior, because that is the behavior im looking for, but I may not be expressing it correctly in Svelte. It may not be the expected behavior of the code.
    3. My mental model has always been that a reactive declaration like $: b = a * 2 defines b in it's entirety ("Here's my recipe for b and all the ingredients, please Svelte make b always up to date"). And outside of this declaration b is immutable.
    4. For me there is a distinct difference between these two scripts: let a = 1; $: b = a * 2; let a = 1; let b; $: { b = a * 2 }; The first example defines a "recipe" for how to create b and b is completely defined by that declaration. Outside of that it is immutable, data flows only into a single sink. The second example declares a variable b and then uses a reactive statement to update it. But it also allows you to do with b whatever you want. If someone wants to go that route (definitely not me), they are free to do so at their own risk of ensuring consistency.
    5. First of all, here is what I meant by updating reactive declared variable
    6. The intention of the issue #2444 was to propagate the changes of the reactive declared variables back to its dependencies. in the context of this example, would meant, updating b should update a as well.
    7. The intended behavior for the code snippet above is to reactively update b when a changes allows b temporarily go "out-of-sync" of a when calling update, setting b to 42 in this case, b is not always a * 2 however, if a changes again, b will be updated back to a * 2, instead of staying at 42
    1. Oh, I just figured out a workaround for my project, in case it helps someone. If you want the source of truth on the prop to come from the child component, then leave it undefined in the parent. Then, you can make the reactive variable have a condition on the presence of that variable. eg: <script> let prop; $: prop && console.log(prop); </script> <Child bind:prop/> Might not work for every use case but maybe that helps someone.
    2. This has been particularly harmful when there is an http API call when val changes ... which triggers the call twice for no reason.
  2. www.metacritic.com www.metacritic.com
    1. Absolutely shockingly awful game from a company that puts out poor quality games. And furthermore, tries to sue YouTubers who don’t like their games for ‘slander’. Shocking games and shocking developers. Avoid at all costs.
    1. Rails 5 recently shipped, and among many other new features is a new renderer that makes it easy to render fully composed views outside of your controllers.
    2. UserMailer has gone untouched and the code remains as clear in its intent and expression as it was when it was written.

      .

    1. When you give an element a width of 100% in CSS, you’re basically saying “Make this element’s content area exactly equal to the explicit width of its parent — but only if its parent has an explicit width.” So, if you have a parent container that’s 400px wide, a child element given a width of 100% will also be 400px wide, and will still be subject to margins, paddings, and borders — on top of the 100% width setting.
    2. This is just one of those things in CSS that seems easy to understand (and really, it should be), but it’s sometimes not — because of the way that percentages work in CSS.
    1. In the "When sending message, automatically" section, uncheck "Place a copy in."

      This seems inconsistent (since we do specify a folder for Drafts), but I confirmed that it still gets stored in Sent even after unchecking this. I guess because Gmail adds the Sent tag on the server, whereas with a draft, it is initiated client-side so the client has to be responsible for adding that tag.

    1. Click Done, sign in with your Google account if prompted and that's all!
    2. The ticket which tracks issues using Gmail with Thunderbird (Bug 402793)

      Notice how it was created >= 14 years ago and is still open.

      Notice how they just keep updating it by adding "Depends on:" "No longer depends on:" (cleaner than adding the details of those related/sub issues directly here)

    1. So if you subscribe to both Inbox and All mail you are in practise downloaded your mails twice. If you then delete a mail in inbox it doesnt go away in All mail. It just get the trash-tag. In my opinion you should never subscribe to All mail. You never need to see it. All you need to see are INBOX, TRASH, SENT and the folders YOU created in your gmail-account.
    1. Thunderbird determines connection details (such as ports, server names, security protocols, etc.) by looking up your email provider in a database that contains connection information for all the major Internet Service Providers (ISPs). After determining the provider of your account (as specified after the "@" symbol in your email address) Thunderbird can usually provide the account details.
    1. Google/gmail calls apps that don't support OAuth2 "less secure". But, that doesn't make them insecure. So what it means is gmail's meaning of LessSecureApp is basically anything that doesn’t use OAuth2.
    2. When you initially logon with OAuth2, you will be redirect to Google’s sign-in page,. Once you have signed in, Google issues you a special OAuth2 token which is saved in Thunderbird and can be seen in the same place as passwords. So when you next logon to gmail, it is using that unique OAuth ID instead of password.
    1. Thunderbird provides the ability to archive messages - that is, to move them from the default folders to archive folders without deleting the messages altogether. This makes it easy to organize archives or move them to a backup device, and keep the Inbox clean. Messages can only be archived manually, not automatically.
    1. Mailspring isn't VC funded and doesn't need to make millions to succeed. Just a thousand paid subscriptions will make Mailspring a stable business and we have big ideas for the future of email.
    1. Even if you didn't intentionally make any changes, please check that this setting is enabled.

      Similarly...

      I noticed in 2 of the 3 accounts I had set up in Geary that IMAP access was disabled. I don't remember disabling it.

      Geary had downloaded from all 3 of these accounts on 2021-12-15, but was not able to today 2022-01-10.

    2. If there is still a problem, try clearing Captcha again.  I acknowledge you wrote that you already did this, but you must open that page using the account that you are setting up in Thunderbird.  If you are signed into multiple Google accounts, the page will open with the primary account.  To be certain that you have used the correct account, please try again after signing out.

      This is a real usability issue.

      That page (https://accounts.google.com/b/0/DisplayUnlockCaptcha) doesn't even tell you which account is active or give you any way to switch.

      As a guess, I tried changing the number, like this: https://accounts.google.com/b/3/DisplayUnlockCaptcha to the same number as I saw in the URL for the account that I wanted to affect: https://mail.google.com/mail/u/3/#inbox and I think it worked (but again, no way to know for sure which account was affected).

    1. Cryptocurrencies are not only an apocalyptic ecological disaster
    2. are also incredibly toxic to the open web, another ideal that Mozilla used to support

      how so?

    3. “Money corrupts; bitcoin corrupts absolutely. Disregarding all of bitcoin's shortcomings, a financial instrument that brings out the worst in people—greed—won't change the world for the better.” —https://www.cynicusrex.com/file/cryptocultscience.html.
    1. The highest rating Pure Health Fungus Eliminator got on Amazon is 4.0/5 stars. Meanwhile, it got 4.9 stars out of 5 on its official website. I’m not saying that the higher rating is entirely biased. But I just think that we get to see more honest reviews outside its site.
    1. I wish there's some kind of an optional ghost or something that I can follow after a while to teach me why I cannot get past a certain area.

      I've wished for this in Mario Maker 2, esp. since you can't just open the level in the editor to see where to go like you could in MM1.

    1. For example, given a website's normal communication method is the internet, out-of-band communication may be by a voice call.
    2. Out-of-band communication may even be by beeps from the PC speaker on the server's Motherboard.

      Huh? Please elaborate. Why/when would it do this? Who would be there to hear the beeps?

    1. Your character feels nigh impossible to control - you move very very fast, but if youre in the air, you dont stop moving the moment you stop holding a direction, so you have to constantly cancel out your momentum to stop, but if you dont do it perfectly you suddenly fly in the other direction
    1. TLDR: Amateur and poorly executed "Qix" type arcade game. Play Lightfish instead. It uses the same core concept but executes much better.http://store.steampowered.com/app/116120/Lightfish/E

      nostalgia (for me) and comparison: Qix

    1. I bought this game in order to review it, seeing as there were no current reviews for it. I thought I'd help the game out by maybe giving it that tiny bit of publicity it needed to get off the ground.
    1. This is the kind of game that, if the quality was better, I might give it a maybe, if Steam offered one.
    1. A good riddance from the ultra realistic modern 2021 games . Or maybe its my personal opinion that most games towards the better side should be like 16-bit only. It certainly took me back to the era of Nintendo when I frankly used to enjoy gaming the most. The look and feel of Tobe's quite resonates with good old konami games, Contra, adventure island, Super Mario, Circus Charlie, Dangerous Dave.
    1. It seems like it could be a good game but its really poorly executed,
    2. Unique concept that could have end up as a great game, but sadly got destroyed by lack of polish .
    1. Code that is per-component instance should go into a second <script> tag.

      But this seems to conflict with https://hyp.is/NO4vMmzVEeylBfOiPbtB2w/kit.svelte.dev/docs

      The load function is reactive, and will re-run when its parameters change, but only if they are used in the function.

      which seems to imply that load is not just run once for the component statically, but rather, since it can be reactive to:

      url, params, fetch, session and stuff

      may be sufficiently like a per-instance callback, that it could be used instead of onMount?

  3. Dec 2021
    1. A plumber was a man who used lead for many reasons. Since lead was very malleable and had a low melting temperature it was employed quite a great deal to seal and repair.Pipes used to be connected and secured just as they are at present, although now we use plastics or ceramics.
    2. One may think that the pipes leading to the sink, and the job of installing or maintaining them is described as plumbing since pipes were previously made with lead and the Latin word for lead was plumbum (consequently the elemental letters Pb).While this fact is absolutely valid, it is additionally true that plumbers were once employed in additional ways than installing pipes when the phrase plumber originally became popular in French then English within a century around the 14th Century A.D.
    3. Furthermore, lead is very weighty and so it was often used in the role of a weight. At the end of a twine hung to be certain of a perpendicular line it is described as a plumb bob. Persons in charge of water workings earlier than the era of dependable pressure systems had to fall back on on gravity defined methods and so accurate lines and levels were essential.
    1. The diagram raises an interesting question which you may not have thought about before. How does all the information from the internet get to the right device inside the network? If you visit howtogeek.com on your laptop how does it end up on your laptop and not your son’s desktop if the public-facing IP address is the same for all devices? Advertisement pagespeed.lazyLoadImages.overrideAttributeFunctions();tmntag.cmd.push(function(){tmntag.adTag('purch_Y_C_0_1', false);}); This is thanks to a wonderful bit of routing magic known as a Network Address Translation (NAT).

      may not have thought about before

    1. If you're using bash, you don't need to use sed to do string replacements (and it's much cleaner to use the replace feature built into bash).
    1. We tag and release gems according to the Semantic Versioning principle. As a result of this policy, you can (and should) specify a dependency on this gem using the Pessimistic Version Constraint with two digits of precision.

      you can (and should)...

    1. Nested contexts tags are overwritten not merged: TestProf::LetItBe.configure do |config| config.default_modifiers[:freeze] = false end context "with reload", let_it_be_modifiers: {reload: true} do # uses freeze: false, reload: true here context "with freeze", let_it_be_modifiers: {freeze: true} do # uses only freeze: true (reload: true is overwritten by new metadata) end end

      good clarification

    2. config.define_derived_metadata(let_it_be_frost: true) do |metadata| metadata[:let_it_be_modifiers] ||= {freeze: true} end
    3. Thus it's not easy to refactor existing tests which use let/let! instead.
    1. It's well-suited for dev/test since it doesn't need an external infrastructure, but it's a poor fit for production since it drops pending jobs on restart.

      .

    1. declaration accepts: | null | [] | [null] | [{foo: 'BAR'}] ------------------------------------------------------------------------ [Vote!]! | no | yes | no | yes [Vote]! | no | yes | yes | yes [Vote!] | yes | yes | no | yes [Vote] | yes | yes | yes | yes
    2. [Vote!]! means that the field (in this case votes) cannot return null and that it must resolve to an array and that none of the individuals items inside that array can be null. So [] and [{}] and [{foo: 'BAR'}] would all be valid (assuming foo is non-null). However, the following would throw: [{foo: 'BAR'}, null] [Vote]! means that the field cannot return null, but any individual item in the returned list can be null. [Vote!] means that the entire field can be null, but if it does return a value, it needs to an array and each item in that array cannot be null. [Vote] means that the entire field can be null, but if it does return a value, it needs to an array. However, any member of the array may also be null.
    1. I could look into this more to understand where things are going wrong, if you can suggest to me which part of the way this is working might be off.

      where even to look?

    2. Besides that configuration, SvelteKit is just a normal Vite project that does rendering on both SSR and client-side.

      "is just..."

      This description makes it sound simple

    1. Two wrongs don't make a right We should fix it in popper core. I sent a PR there: floating-ui/floating-ui#1342

      .

    2. Just import it the normal way. Then Vite can use the CJS version on the server-side and ESM version on the client-side. Forcing it to always be ESM breaks SSR with the latest SvelteKit.

      .

    1. The code isn't going back to the way it was So otherwise you'll be stuck on an old version forever...

      In reply to:

      PS. I will stay with 144 for a while...

    1. Deeply importing Svelte components is not supported. Either import all components from one entrypoint, or always stick to deep imports, otherwise it could cause multiple instance of the Svelte library running.
    1. underscores are better than dashes for representing spaces

    2. So, underscores are not quite as good as spaces. They’re a compromise of language, readability, and semantics, but they’re the best we’ve got. Better than dashes, CamelCase, plus+signs, or anything else. So use them.
    3. The “use spaces, or else fall back on quotes” system is just silly.
    1. It allows you to access common components and utility modules without ../../../../ nonsense.

      well said :)

    1. The difficulty is that the square brackets accessor doesn't allow a straightforward way to access items from the end of the array, and also doesn't accept a negative index.
    1. A Map of root-level context key-value pairs to supply to the component
    1. This means that underscores allow humans to be able to space out the words used, but computers lack the ability to do so.

      whatever, that's not true

    2. This is because using hyphens instead of underscores makes it easier for Google’s web crawler to compute the information that your website has and create consistent results.
    1. The product may not be compatible with routers or gateways with firmware that has been altered, is based on open source programs, or is non-standard or outdated

      It what way? Why not? Wouldn't it just connect to them with standard Wi-Fi protocols like any other device?

    1. Just FYI, there is a nice way to "expect a change" in RSpec. You don't have to use it, what you have is fine, just thought I'd share. expect { widget.paper_trail.update_columns(name: "Bugle") }.to(change { widget.versions.length }).from(1).to(2)
    2. I'd prefer a "guard clause" here. return unless enabled?
    1. TylerRick commented
    2. Wait, I'm still interested in a solution to this problem/need! (no activity doesn't necessarily = no interest. I totally understand if the maintainers just aren't interested in implementing this and would rather someone submit a PR... but would it have been any different if I'd pinged this thread every 5 months to show continued interest? )

      no activity doesn't = no interest

    3. To be more clear, it violates this particular rule.
    1. For what it's worth, accessing attributes with [] is not the same as using send. The latter will call the accessor method, which is what you want 99/100.
    1. The decision to use a "keep it clean" design for the user interface sometimes takes it a step too far.
      • design decisions
      • taken too far
    1. The props used for each slot inside the Tooltip. Note that componentsProps.popper prop values win over PopperProps and componentsProps.transition prop values win over TransitionProps if both are applied.
    1. If you want to restore the old behavior (thus not reaching level AA), you can apply the following diff: -<Tooltip> +<Tooltip disableInteractive> # Interactive tooltips no longer need the `interactive` prop. -<Tooltip interactive> +<Tooltip>

      How would you even apply this "diff"? I assume this is supposed to just be a hint for what you should look for and either manually or automatically do a global search and replace for (no search and replace tool that I know of accepts a diff instead of search and replace strings, but I guess they are functionally the same thing).

    1. In order to work with Safari, you need at least one display block or flex item below the tooltip wrapper.

      special treatment

  4. www.kickstarter.com www.kickstarter.com
    1. A co-operative card game about assembling flat-pack furniture with your partner, and definitely not about your collapsing relationship.
    1. games that take a fast-moving sport and turn it into a slow-moving, thinking, turn-based game of strategy

    1. make you more prepared for spontaneous things in life, like when you get asked a question in the middle of nowhere, your brain usually freezes up and can't think of an answer. This game captures that entirely.

      to capture the essence/feeling of something

  5. Nov 2021
    1. trying to counter the antivaccine movement predicted that antivaxxers would publicize and weaponize reports of death and adverse events after COVID-19 vaccines to give the impression that the vaccines are dangerous

      That's ironic. That's exactly what the vaccine-pushers are doing: over-reporting the danger of the Covid virus.

    1. When the embedded document has the same origin as the embedding page, it is strongly discouraged to use both allow-scripts and allow-same-origin, as that lets the embedded document remove the sandbox attribute — making it no more secure than not using the sandbox attribute at all.
    1. Fixing with containIf we give each article the contain property with a value of content, when new elements are inserted the browser understands it only needs to recalculate the containing element's subtree, and not anything outside it:
    1. There is so much good stuff going on here.
    2. What a time to be alive!
    3. The complex typewriting effect is abstracted away in a neat function, out of site and out of mind.
    4. this action is re-usable. Anytime you want a typewriter effect added to an element, you just import the function and apply it. So elegant.
    5. All that is left is use:typeWriter. You instantly understand what it does and so will probably any future colleagues.
    6. Some call them the lifecycle methods of elements which I think is an apt description.
    7. Actions are deceptively simple yet incredibly powerful.
    1. Yep, we experimented with this, but what we found is that you loose most of Svelte's niceness like slots, and instead you'll pass around deeply nested objects.
    2. Now this is getting too complex for discussing this here and these type of architectural decisions require more in depth understanding than what I can provide here.
    3. My UIs are data/store driven. The UI is just a way to visualize the data. Your data could flow through all of of the extensions and the extensions can make decisions (e.g. setting visible to false). Like middlewares in a Connect/Express/Polka app. And the UI doesn't even know about all this, it just updates with the current state and makes sure it's consistent.
    4. (you can get pretty far with <svelte:component> and passing component constructors around and spicing up props along the way)
    5. Abstract the whole queryCommandState / execCommand system into a store (or some wrapper that also holds a store) that has state like isBold and canMakeBold and a makeBold() function.
    1. You sure packed lot of good lessons and important concept explanations/illustrations into this little answer/tutorial. Well done.
    2. The consumer component will barely change from our last example. The only difference is the way we'll get a reference to our store (since now the store is exported from the JS module):
    3. In effect, the $ syntax we've seen above will actually setup a subscription to the store. And the subscription will be cancelled when the component is destroyed. If the store is subscribed by multiple components, the store will be disposed only when the last component unsubscribes (it will be reinitialized, if a new subscription is made). This is very handy to manage the lifecycle of disposable things in your code.
    4. <!-- you can use the $ prefixed value directly in the template --> <!-- (so we actually don't need the reactive expression above, in this example)
    5. lifecycle is also managed automatically by Svelte
    6. (And we've covered 75% of the store topic... They're efficient, to the point... And simple!)
    7. Now your whole WS logic can be encapsulated in your JS module. That makes for good separation of concern.
    8. In order to use this, we need to use a little more advanced readable store. Here's your example updated for this:
    9. In your Svelte component, you can then use your store with the special $ prefix syntax, to access the value of the store ('cause the temperature variable is a reference to the store itself, it's just a mean to our end, the result we need is the value):
    10. // our temperature is now a store with initial value 0 const temperature = writable(0); // now we don't need to change this function, the change will be propaged // by the store itself const getTemperature = () => { return temperature; }
    11. Here's how we would rewrite our callback example with a store instead:
    12. Same as our callback example, except they offer a handful of other very useful tool (like computing derived values from other stores), and also a slick syntax in the Svelte component.
    13. Stores are essentially some kind of simplified streams (or Observable as they're called in ES), that is they represent a value over time.
    14. Stores are the idiomatic Svelte way when you need to import "reactivity" from your normal JS sources.
    1. Personally, I prefer an event-based communication, but I don't think it's actually better. The only problem with props is that it can cause problems if badly managed, but normally, both of them are ok. In real life, I would opt for storage.
    1. Interim summary

      .

    2. Finally, I think Actions are great for animations, because you will definitely need to apply the same logic to many different elements. One of my favorite examples are FLIP animations, where a change in DOM position can be animated. For example shuffling a list of items. I will not dive deep into the topic in this article: I've written about some techniques in this article about FLIP animations in React and in this article about how to create spring animations with Web Animation API. Although they are not about Svelte, at the end of the day it all boils down to manipulating the HTML element directly. And Svelte Actions are a great place to do it.
    3. We also need at least something in our CSS that can be set from outside. CSS custom properties are a great fit for this!
    4. But you can get quite close to directly updating CSS with Actions!
    5. export function autofocus(node) { node.focus(); } That's it. This is a legitimate Svelte Action!
    1. To match against an ID or selectors that do not follow standard CSS syntax (by using a colon or space inappropriately, for example), you must escape the character with a backslash ("\"). As the backslash is also an escape character in JavaScript, if you are entering a literal string, you must escape it twice (once for the JavaScript string, and another time for querySelector()):
    1. export interface TasksListSpecifics { 0: ('parallel' | 'sequential'); } export type TasksList = (string[] & TasksListSpecifics); Or more compact: export type TasksList = (string[] & { 0: ('parallel' | 'sequential'); }); The trick is to add your more specific properties on top of array of string type (Array<string>).
    2. add ! to the end of the var that is being spread. E.g. [{}, ...payload!]
    3. This also happens with an interface that fakes a tuple: interface Foo { 0: string; 1: number; 2?: boolean; // can't have an optional member in a real tuple }
    1. Notice that in the else branch, we don’t need to do anything special - if x wasn’t a string[], then it must have been a string.
    2. It might be confusing that a union of types appears to have the intersection of those types’ properties.
    3. the name union comes from type theory. The union number | string is composed by taking the union of the values from each type. Notice that given two sets with corresponding facts about each set, only the intersection of those facts applies to the union of the sets themselves.
    4. For example, if we had a room of tall people wearing hats, and another room of Spanish speakers wearing hats, after combining those rooms, the only thing we know about every person is that they must be wearing a hat.
    5. Animal & { honey: boolean }
    6. Extending a type via intersections
    7. Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
    1. Inside each first-level directory of a MAFF archive, the second-level directory named ^metadata^ (case-sensitive) is reserved and should not contain actual content. A file or folder named ^metadata^ (case-insensitive) should not exist inside any first-level directory.
    1. Support for reading and writing MAFF archives was provided in the Mozilla Application Suite, Firefox, and SeaMonkey thanks to the Mozilla Archive Format add-on from 2004 to 2018. While the original add-on is no longer maintained, the file format specification is still available and can be referenced by third-party software to provide better interoperability.
    2. MAFF files are standard ZIP files containing one or more web pages, images, or other downloadable content. Additional metadata, like the original page address, is saved along with the content.
    3. Unlike the related MHTML format, MAFF is compressed and particularly suited for large media files.
    1. Docker Desktop remains free for small businesses (fewer than 250 employees AND less than $10 million in annual revenue), personal use, education, and non-commercial open source projects.It requires a paid subscription (Pro, Team or Business), starting at $5 per user per month, for professional use in larger businesses. You may directly purchase here, or share this post and our solution brief with your manager.While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription to use Docker Desktop.
    1. Thanks to the positive support we received on the subscription updates, we’ve started working on Docker Desktop for Linux which is the second-most popular feature request in our public roadmap.

      listening to users

    1. I received an Appraisal Award letter for a claim to have my roof replaced for a total amount of $16000. The insurance paid the first half of 9100 for the Actual Cash Value and stated that the difference which is the depreciation amount was going to get paid after the work gets completed. It was completed and now the insurance is stating that because the amount on the roofers bill was less than the total awarded amount that they won't pay the rest. I can either have the roofer send an itemized final bill to show the depreciation cost in addition to the first bill that didn't show the breakdown or additional costs... OR I shouldn't have to go through this because the awarded amount is due regardless because the job was completed as requested. I need help to recover my depreciation amount owed.

      Seems complicated... and leaves them too many ways to wiggle out of paying.

    1. As a solo dev I find this review totally unfair and rude! This game has been made by one person and hundreds of hours have gone into it... To say 5 hours max has been put into this project is just a ignorant negative response.
    1. Modern browsers that support the File System Access API (Edge and Chrome today) allow web pages to access the local file system (with your permission).
    2. Like a lot of people who buy a .dev domain, we had no idea what we were going to do with it. And we certainly didn't anticipate that it would end up being the fulfillment of a mission over a decade in the making.

      didn't know what they would do with it, but knew they might want it someday :)

    1. con: doesn't let you define after_transaction callbacks anywhere like ar_after_transaction does (outside of the after_commit, etc. callbacks which only happen at certain points in the model's life cycle)
    1. .. isn't just a shell shortcut; it's a very real entry in the file system for the parent of the directory it is contained in.

      May matter some times?

    1. So it actually replaces the file, not update? If that file is hard-linked, the the other link is unaffected?
    1. It's all too complex for our little brains to handle. And like any situation of excess complexity, we collapse dimensions until we have a structure we can comprehend. The problem, in this case, is that our simplifications create tunnels large enough for the trucks of hacker to drive through—with ease.