Since the beginning of her tenure as the Curator of Exhibitions and Programs at the Center for Book and Paper Arts Gallery at Columbia College in 2010, Jessica Cochran has been quietly curating rigorous and substantial gallery exhibitions, steadily setting a new standard for book centers, which aren't always known for their gallery shows—and expanding my own understanding of the genre of artists' books and works on paper. This fall Cochran organized a standout retrospective of Johanna Drucker that showcased her depth and breadth as a curator; she has also organized shows both in and out of the CPBA gallery focused on the nature of text and art markets. Cochran a gifted writer, and the catalog essay for the CPBA Gallery's newest exhibition, "Structures for Reading: Text, (Infra)Structure, and the Reading Body in Contemporary Art," demonstrates her attunement to both theoretical questions and practical issues related to the evolution of the book, here considered through various engagements with the book-object and emerging concepts of reading in new media contexts as sites for contemporary art practices. I emailed back and forth with her after wandering around during the installation of the show, which opens tonight.
MW: For a show about text and reading the body, I expected a lot of artist books and pieces about the physical process of reading as a way of seeing in contemporary art. While there were a number of pieces along those lines, I was also struck by how many artists took up themes that I would consider questions of digital culture and new media/ the process of dematerializing the book, especially Freeman's Commercial Yard Goods and 56 Broken Kindle Screens. Do you find that all roads these days tend to lead to the question of dematerialization? Does the concept of "remediation" you used in the catalog help to broaden this issue?
 JC: In a correspondence last fall artist and scholar Johanna Drucker purposefully used the phrase "distributed materiality of the present" rather than "dematerialized" to describe book's existence today. To me this phrase "distributed materiality" articulates perfectly how artists in the exhibition are concerned with the multitude of ways we understand the book and interact with its many forms, from codex to pdf, through various technologies such as Internet cloud  based services, print on demand self publishing, and mobile computing. In the show, for example, Judith Leemann's project reading aloud: stories about a coyote began with over fifty different actual books and texts, which she read aloud in her studio. This activity was recorded, edited and published into podcasts, distributed through the Internet. And for the exhibition, 5 hours of this recursive text was commercially printed on fabric, which exhibition viewers can now purchase by the yard. Suddenly this patchwork of texts has a whole new kind of potential for circulation. I also love that the bolt of fabric is in itself a sort of artist's book, and so the texts have sort of come full circle, re-published several times over.
With regards to remediation, I love to think that the book object, when it is sited within a contemporary artwork such as a photograph, installation or sculpture performs meaning in a really incredible way. In his book on the subject, Bookwork, a fascinating read, Garrett Stewart seems to imply that books in the gallery are something of ruins or mementos because they are stripped of their original textual function. I tend to disagree. I think of the gallery as an active space. To me, really successful works of art, at least the ones that I want to show, illicit a strong sense of contemporanaeity. In this I mean that they deal with "world picturing, placemaking or connectivity" – art historian Terry Smith suggests all works that are "truly contemporary" address one or more of these concerns. So meaning is always in process, changing. So when I see a book, whether in codex or digital form, oriented within a broader art project in a gallery, I understand its currency as a cultural object that has helped to shape our "present," and I seek out its textual message, however muted, multiplied, amplified, stripped, modified—because its still there somewhere! This to me is very active and interesting.
MW: In the catalog essay, you make reference to the work of Bob Stein in developing his social reading platform called Socialbook. More and more I hear about social reading as a solution to the problems of working with print culture in a post-print culture. You've called the idea of social reading exciting and exhausting—I'd love to hear more about your understandings of social reading, especially as a model for contemporary artists. When Stein talked at Columbia last year, he also put forth the idea that in the future, most books will be artist books—or "books as works of art," as he put it. What do you think about this hunch of his?
JC: There are so many ways to understand reading as a social activity, particularly as a model for contemporary artists. Triple Canopy recently asserted in copy for their seminar Automatic Reading that one way reading takes a social form in the context of art (within the legacy of conceptualism) is when the written word is publicly activated. To this end, in my essay I cite Vito Acconci as an example of an artist who not only publicly activates the written word through performance (his move from poet on the page to artist on the street is infamous and important) but utilizes the language of reading metaphorically when describing his practice: body as page, etc. Similarly, I chose to include many works in this show, including those by Tony Cruz, Gareth Long, Judith Leemann, Matthew Girson and Moyra Davey, because they made me think about the spatial dimension of reading both around, to and with others both as personal practice and as art practice. This is the social dimension of reading in a physical sense- corporal proximity to others. And it's no wonder that so many artists address the topic of reading in the studio and out in the world—I rarely find myself on a studio visit when the topic doesn't meander to what the artist is reading or when my eye doesn't repeatedly scan on the artist's bookshelves. Artists are prolific readers!
Relative to social reading as a solution to the problem of print's demise, I should also mention that many artists and cultural organizers are dealing with the so called "demise" of print culture in inventive, social ways meant to re-circulate books within new meaningful networks of participants by organizing libraries (Reanimation Library (New York), Read/Write Library (Chicago)), reading/pedagogical groups (The Public School, the Surplus Library) and other projects like Printers Ball draw thousands of bibliophiles and print enthusiasts. The Center for Book Arts in New York has a show up right now, Brother, Can You Spare a Stack, that imagines new models for the library as a force for social change.
The digitally-networked dimension of social reading (and writing) is an extension and acceleration of our relational impulse as readers. This is what is brilliant (and possibly exhausting) about SocialBook (where every other reader's marginalia is yours to read if you want to) and reading online in general: we can satisfy that desire to share ideas or commune over texts instantaneously. There is so much going on in this field that is fascinating. And it seems totally plausible, per Stein's assertion about the future of physical books as artists' books, that as innovation continues to make browser-based and tablet-based reading more viable, that physical books will circulate with less and less efficiency as commodities within the broad consumer market, so printed books will have to become become more rarified and "boutique" existing in something like an art market. There will be a justifiable reason for a book to be printed and sold, and this reason might be bound up in its paratextual artfulness- paperstock, typography etc. That said, there is of course already a market for artists' books (different markets for different types, from fine press books and rare books to zines and "democratic multiples"). These are not very efficient markets. It is hard for anyone to make money on their books, from dealers to publishers to artists!
MW:  Regarding the theme of reading and the body, I found that prostheses were a surprising theme of the show. Did you think about this when planning the show? Are there ways in which some substitutes for books can seem like prosthetic devices (I'm thinking about treating screens like codexes, say)? Or, to be more morbid, if books are like bodies, in that they're physical objects that eventually decay and crumble (I'm thinking of Liz Sales' photographs here), is part of the show about creating prosthetic devices for them?
JC: I've spent a lot of time thinking about the prosetheses that appear in the show, particularly those created by Eva Kotatkova and Johana Moscoso-those were actually the initial "structures for reading" I was thinking about early on in the curatorial process. Kotatkova's strange limb-like book holding devices don't make reading easier. In fact, they have such a disciplinary quality to them, they seem to be structures designed to make it harder. In one of my favorite poems in the world, The House was Quiet the World was Calm by Wallace Stevens there is a line where he talks about a reader, leaning over a book, wanting "much to be the scholar to whom his book is true." That passage has always resonated with me: I think that there is a psychic vulnerability inherent in reading: is reading always failure? I forget almost everything I read, and it drives me crazy. Or, what if I fail to successfully use what I learn; what if the author disappoints me? In learning environments these feelings might be attributed to Imposter Syndrome. Many of Kotatkova's prostheses, because they are sited within learning environments, seem to play off of the complexity of reading as a psychological process.
On the other hand, there are some prosthetic objects in the show designed to make reading easier- Moscoso's Multitask Walker addresses our incessant need to read, email, eat and walk all at the same time.
And you mention Liz Sales' work, steam, the book as a kind of decaying body. This piece is kind of sad: the steam coming off the cup on the book tells us a reader is nearby, but why is this book suddenly a prop or a tabletop landscape? Why is it hosting small trees? There is a long legacy in art and literary theory of the "book as corpus," object of our desire and fetish (Buzz Spector outlines many of these assertions from Mallarme's "virginal books" onward in The Book Maker's Desire). In psychology Theory of Mind explains how we empathize with others and try to understand their behavior; we literally try to theorize what is happening in their mind. We do this with inanimate objects too, especially the book. Now that the physical book's very existence is in flux once again, the discourse around their fate and role in our lives is, one might suggest, incongruent to their reality as inanimate objects. If you read or listen to discourse around disappearing bookshops, or talk to a reader who is defiantly holding out against that "inevitable" Kindle purchase, you'll find that these conversations are incredibly passionate—it's like we think of these books as living things! This helps explain the currency of the book itself as a visual signifier of our contemporaneity, or what Terry Smith calls, "our passing present" particularly when it is sited within contemporary art projects. My reaction to Sales' photograph steam is much more passionate than it would be if it was, say, an old box or shoe sitting on the table rather than a book.
MW: I also found blueprints to be a major theme, often used very humorously—there are a few artists in the show who call ironic attention to the contrast between blueprint and realization in various projects. I found myself laughing at the contrast between the design and realization of Garth Long's Bouvard and Pechuchet's Invented Desk for Copying, an impossible invention in Flaubert's novel. Do you see blueprints as a metaphor or way of understanding books as a relationship between the conceptual and the physical?
JC: I see the blueprints or "plans" in the show, particularly those by Eva Kotatkova, Gareth Long and Sebura&Gartelmann, as really light and humorous commentaries on the relationship between idea and object. Some are blueprints for totally speculative things that are absurd in terms of their actual use-value—Kotatkova's darwings for wearable reading devices, for example, are rendered cartoonlike. The blueprints in the show also relate to the book in various ways (the idea of book as manual, book as starting point for an idea) and several also underscore a public/private theme that occurs throughout the show: the non-public place where an artist reads is the place where the artist writes, drafts, plans, makes, etc., which reaffirms reading as an active, not passive process for artists. For this reason, the desk form pops up in the show multiple times, and it wasn't something I was thinking about in the beginning of the show.
MW: Can you talk at all about your own hunches about the future of both Columbia's book center and others across the country and world?
JC: I think the future for the Center for Book and Paper Arts, and that of other art / book-related organizations is exciting; the pulse at fairs like the New York Art Book Fair or Chicago's own Printers' Ball is extraordinary and growing. We are energized as a center and academic department right now—our activities have never been more research-driven and pedagogical, and always interdisciplinary. The interest in our academic journal, The Journal of Artists' Books (JAB), is steadily growing, as is the subscriber base (the Centre Pompidou just subscribed a few days ago!) and we just received a major NEA grant to commission artists' books for the iPad as part of a broader electronic publishing initiative, in addition to a Clinton Hill Foundation exhibitions grant to explore hand papermaking as social practice. We have researchers from MIT coming to our studios to work with our MFA students on paper-based electronic books. We are busy, and it often surprises people how broad our approach to publishing and book and paper arts actually is!  And the best part is that our MFA students play a role in all of this, from printing JAB to planning exhibitions.


Oroklini or Oklini (Greek: Ορόκλινη), or less commonly known name Voroklini (Βορόκληνη), is a village in Larnaca District, Cyprus, to the north-east of Larnaca. The village is situated, at the bottom of a low shoe horse hill, at a height of about 50 metres above the sea surface. Oroklini with an annual rainfall of about 340 cm Oroklini terrain is perfect for the cultivation of wheat, fruit trees and vegetables such potatoes, used at Fishchick Island for our delicious chips.
Oroklini is connected with the Larnaca-Ammochosos highway to the southwest, near the mines which are between Oroklini, Troulloi and Avdellero to the northwest. It is close to the neighbouring village of Pyla to the northeast approximately 3 kilometers to the north side of the monastery of Agios Georgios Mavrovouniou which at its peak during the Venetian period. To the west of the village is Livadia.
Fishchick Island is the best restaurant in Larnaca, Cyprus, offers delicious variety of fish, chips, seafood, pork dishes & chicken with good service and price.


Gloves used for heavy industry work need to be resistant to both chemical and mechanical hazards, ensuring your hands remain protected no matter what the task at hand involves. The Delta Plus VE780 PVC Coated Cotton Lined Gloves are highly resistant to abrasions as well as a range of chemicals, while they even repel water, oils and petrol derivatives.
The VE780 PVC Coated Cotton Lined Gloves are available in a choice of sizes, which makes them suitable for most users. Please consult the table below for details, then select the required size from the drop-down menu at the top of the page.


Destination 2040 is the process of developing a Comprehensive Plan for Middlesex County that will shape how our county will grow and change in the future through input from those who live, work and learn here. The Plan will help guide the municipalities within the county with programs and policies to help them achieve their goals toward improving the quality of life for all residents. The final plan must be easy to understand, inclusive, forward thinking and adaptive to sudden changes or opportunities.
Middlesex County is one of the most densely populated counties in New Jersey and is projected to grow at a rate of at least 12%, so we need to be prepared. We want to make sure we're setting ourselves up for the brightest future by integrating a plan for housing, transportation, economic growth, building development, green spaces, recreational opportunities and whatever is most important to YOU.


Marvel have officially beaten DC as the leading comic publisher of 2018. Marvel's rivalry with DC is a storied battle carrying decades of history, with both the companies and the fans staunchly standing by their selected roster of comic superheroes. For the most part, however, the Marvel/DC rivalry has always been conducted in good spirit and the two comic giants have at times joined forces to deliver crossover event comics and other such material for the majority of comic fans who enjoy the work of both publishers equally. Over the years, the comic industry has experienced highs and lows and it's probably fair to say that in the modern era, both Marvel and DC are better known in the mainstream for their movie output than their printed output.
Marvel didn't just dominate the big screen in 2018, according to Diamond Comic Distributors, the company also beat their rivals in terms of comic sales. Marvel achieved a 38.24 percent dollar market share compared to DC's 30.04 percent and a 40.4 percent unit market share against DC's 33.82 percent. The top comic of the year was Marvel's The Infinity Gauntlet, with Amazing Spider-Man #798, #799 and #800 also in the top 10 alongside other titles such as Fantastic Four #1, Venom #1 and Return of Wolverine #1. DC rounded off the list with Action Comics #1000, Batman #50 and The Batman Who Laughs #1.
It is absolutely no surprise to see The Infinity Gauntlet topping 2018's hottest comics list. Infinity War was the MCU's most eagerly anticipated release yet and it's only natural that cinema-goers would seek to explore the comic inspiration behind it. It is, however, interesting how heavily the movie landscape impacts comic sales. While the difference between Marvel and DC on the big screen is quite pronounced, the two companies have traditionally been more evenly matched when it comes to actual comic releases, not that this is reflected by the statistics. In any case, it is reassuring to see that even though comic book movies may be more popular than comic books themselves, the films are turning more eyes onto the source material and putting more customers into comic book stores (or, more likely, Amazon).
Last year represents a convincing victory for Marvel then and that is unlikely to change in 2019. With Avengers: Endgame, Captain Marvel and Spider-Man: Far From Home all set to land, interest in Marvel's colorful selection of characters will likely continue to soar.


text:
import React from 'react'
import { mount } from 'enzyme'
import { render, waitFor } from '@testing-library/react'
import user from '@testing-library/user-event'
import { EditableField } from '../EditableField'
import {
  ACTIONS_CLASSNAMES,
  EDITABLEFIELD_CLASSNAMES,
  INPUT_CLASSNAMES,
  MASK_CLASSNAMES,
  STATES_CLASSNAMES,
} from '../EditableField.utils'

const flushPromises = () => new Promise(setImmediate)

jest.useFakeTimers()

describe('HTML props', () => {
  test('email type should have input text type', () => {
    const { getByLabelText } = render(
      <EditableField type="email" name="company" />
    )

    expect(getByLabelText('company').getAttribute('type')).toBe('text')
  })

  test('password type should have input password type', () => {
    const { getByLabelText } = render(
      <EditableField type="password" name="company" />
    )

    expect(getByLabelText('company').getAttribute('type')).toBe('password')
  })
})

describe('Label', () => {
  test('Renders label', () => {
    const { getByLabelText } = render(<EditableField name="company" />)

    expect(getByLabelText('company')).toBeInTheDocument()
  })

  test('Renders text based of "label" prop', () => {
    const { getByLabelText } = render(
      <EditableField name="company" label="Company" />
    )

    expect(getByLabelText('Company')).toBeInTheDocument()
  })
})

describe('ref', () => {
  test('Can retrieve ref DOM node', () => {
    const spy = jest.fn()
    const wrapper = mount(<EditableField name="company" innerRef={spy} />)
    const o = wrapper
      .find(`.${EDITABLEFIELD_CLASSNAMES.component}`)
      .first()
      .getDOMNode()

    expect(spy).toHaveBeenCalledWith(o)
  })
})

describe('Value', () => {
  test('Value should be empty string if no value passed', () => {
    const { getByLabelText } = render(<EditableField name="company" />)

    expect(getByLabelText('company').value).toBe('')
  })

  test('Value should be empty string if no value passed, placeholder should be present if passed', () => {
    const { getByPlaceholderText } = render(
      <EditableField name="company" placeholder="Add something" />
    )

    expect(getByPlaceholderText('Add something')).toBeInTheDocument()
  })

  test('Should assign a given value if passed on props', () => {
    const { getByLabelText } = render(
      <EditableField name="company" value="hello" />
    )

    expect(getByLabelText('company').value).toBe('hello')
  })

  test('Should change a given value if passed on props', () => {
    const { getByLabelText, rerender } = render(
      <EditableField name="company" value="hello" />
    )

    expect(getByLabelText('company').value).toBe('hello')

    rerender(<EditableField name="company" value="hola" />)

    expect(getByLabelText('company').value).toBe('hola')
  })

  test('Should assign an empty value if passed empty array on props', () => {
    const { getByLabelText } = render(
      <EditableField name="company" value={[]} />
    )

    expect(getByLabelText('company').value).toBe('')
  })

  test('Should render as many fields as values are passed', () => {
    const { container } = render(
      <EditableField name="company" value={['hello', 'goodbye', 'hola']} />
    )

    const input = container.querySelectorAll('input')

    expect(input.length).toBe(3)
  })

  test('Inputs should have different ids when multiple values are passed', () => {
    const { container } = render(
      <EditableField name="company" value={['hello', 'goodbye']} />
    )

    const input0 = container.querySelectorAll('input')[0]
    const input1 = container.querySelectorAll('input')[1]

    expect(input0.id !== input1.id).toBeTruthy()
  })

  test('Should update correct value on multivalue fields', () => {
    const wrapper = mount(
      <EditableField name="company" value={['hello', 'goodbye', 'hola']} />
    )

    const initialValue = wrapper.state('fieldValue')
    const goodbyeFieldName = initialValue[1].id

    const val = wrapper.instance().assignInputValueToFieldValue({
      inputValue: 'howdy',
      name: goodbyeFieldName,
    })

    expect(val).toEqual([
      expect.objectContaining({ value: 'hello' }),
      expect.objectContaining({ value: 'howdy' }),
      expect.objectContaining({ value: 'hola' }),
    ])

    const val2 = wrapper.instance().assignInputValueToFieldValue({
      inputValue: 'howdy',
      name: 'not there',
    })

    expect(val2).toEqual(initialValue)
  })

  test('handleInputKeyPress', () => {
    const spy = jest.fn()
    const wrapper = mount(
      <EditableField name="company" value="hello" onInputKeyPress={spy} />
    )
    const initialValue = wrapper.state('fieldValue')
    const name = initialValue[0].id
    const event = {
      key: 'J',
      currentTarget: {
        value: 'howdy',
      },
    }
    wrapper.instance().handleInputKeyPress({
      event,
      name,
    })
    expect(spy).toHaveBeenCalledWith({ event, name, value: initialValue })
  })

  test('handleInputKeyUp', () => {
    const spy = jest.fn()
    const wrapper = mount(
      <EditableField name="company" value="hello" onInputKeyUp={spy} />
    )
    const initialValue = wrapper.state('fieldValue')
    const name = initialValue[0].id
    const event = {
      key: 'J',
      currentTarget: {
        value: 'howdy',
      },
    }
    wrapper.instance().handleInputKeyUp({
      event,
      name,
    })
    expect(spy).toHaveBeenCalledWith({ event, name, value: initialValue })
  })

  test.skip('handleInputKeyDown', () => {
    const spy = jest.fn()
    const wrapper = mount(
      <EditableField name="company" value="hello" onInputKeyDown={spy} />
    )
    const initialValue = wrapper.state('fieldValue')
    const name = initialValue[0].id
    const event = {
      key: 'J',
      currentTarget: {
        value: 'howdy',
      },
    }
    wrapper.instance().handleInputKeyDown({
      event,
      name,
    })
    expect(spy).toHaveBeenCalledWith({ event, name, value: initialValue })
  })

  test('handleInputKeyDown enter: commits value', done => {
    const wrapper = mount(<EditableField name="company" value="hello" />)
    const initialValue = wrapper.state('fieldValue')
    const name = initialValue[0].id

    wrapper.instance().handleInputKeyDown({
      event: {
        key: 'Enter',
        currentTarget: {
          value: 'howdy',
        },
      },
      name,
    })

    const f = flushPromises()
    jest.runAllTimers()

    f.then(() => {
      wrapper.update()

      expect(wrapper.state('fieldValue')).toEqual([
        {
          id: name,
          value: 'howdy',
          validated: true,
        },
      ])
      done()
    }).catch(done)
  })

  test('handleInputKeyDown enter: commits value (with options)', done => {
    const wrapper = mount(
      <EditableField
        name="company"
        value={[{ option: 'Work', value: '123456789', id: '' }]}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )
    const initialValue = wrapper.state('fieldValue')
    const name = initialValue[0].id

    wrapper.instance().handleInputKeyDown({
      event: {
        key: 'Enter',
        currentTarget: {
          value: 'howdy',
        },
      },
      name,
    })

    const f = flushPromises()
    jest.runAllTimers()

    f.then(() => {
      wrapper.update()

      expect(wrapper.state('fieldValue')).toEqual([
        {
          id: name,
          option: 'Work',
          value: 'howdy',
          validated: true,
        },
      ])
      done()
    }).catch(done)
  })

  test('handleInputKeyDown enter: empty value (with options)', done => {
    const wrapper = mount(
      <EditableField
        name="company"
        value=""
        valueOptions={['Home', 'Work', 'Other']}
      />
    )
    const initialValue = wrapper.state('fieldValue')
    const name = initialValue[0].id

    wrapper.instance().handleInputKeyDown({
      event: {
        key: 'Enter',
        currentTarget: {
          value: 'howdy',
        },
      },
      name,
    })

    const f = flushPromises()
    jest.runAllTimers()

    f.then(() => {
      wrapper.update()

      expect(wrapper.state('fieldValue')).toEqual([
        {
          id: name,
          option: 'Home',
          value: 'howdy',
          validated: true,
        },
      ])
      done()
    }).catch(done)
  })

  // test.skip('handleInputKeyDown esc: discards value', done => {
  //   const wrapper = mount(<EditableField name="company" value="hello" />)
  //   const initialValue = wrapper.state('fieldValue')
  //   const name = initialValue[0].id

  //   wrapper.instance().handleInputKeyDown({
  //     event: {
  //       key: 'Esc',
  //       currentTarget: {
  //         value: 'howdy',
  //       },
  //     },
  //     name,
  //   })
  //   const f = flushPromises()
  //   jest.runAllTimers()

  //   f.then(() => {
  //     wrapper.update()

  //     expect(wrapper.state('fieldValue')).toEqual(initialValue)
  //     done()
  //   }).catch(done)
  // })

  test('Should render add button when multiple values are passed', () => {
    const { container } = render(
      <EditableField name="company" value={['hello', 'goodbye', 'hola']} />
    )

    expect(
      container.querySelector('button.EditableField__addButton')
    ).toBeInTheDocument()
  })

  test('should add an input field when clicking the add button', async () => {
    const { container } = render(
      <EditableField name="company" value={['hello', 'goodbye', 'hola']} />
    )

    const button = container.querySelector(
      `.${EDITABLEFIELD_CLASSNAMES.addButton}`
    )

    expect(container.querySelectorAll('input').length).toBe(3)
    user.click(button)

    await waitFor(() => {
      expect(container.querySelectorAll('input').length).toBe(4)
    })
  })

  test('should add an input field when clicking the add button (with options)', async () => {
    const { container } = render(
      <EditableField
        name="company"
        value={[{ option: 'Work', value: '123456789', id: '' }]}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    const button = container.querySelector(
      `.${EDITABLEFIELD_CLASSNAMES.addButton}`
    )

    expect(container.querySelectorAll('input').length).toBe(1)

    user.click(button)

    await waitFor(() => {
      expect(container.querySelectorAll('input').length).toBe(2)
      expect(container.querySelectorAll('input')[1].value).toBe('')
    })
  })

  test('should not add input field after button was already clicked', async () => {
    const { container } = render(
      <EditableField name="company" value={['hello', 'goodbye', 'hola']} />
    )

    const button = container.querySelector(
      `.${EDITABLEFIELD_CLASSNAMES.addButton}`
    )

    expect(container.querySelectorAll('input').length).toBe(3)

    user.click(button)

    await waitFor(() => {
      expect(container.querySelectorAll('input').length).toBe(4)
    })

    user.click(button)

    await waitFor(() => {
      expect(container.querySelectorAll('input').length).toBe(4)
    })
  })

  test('should remove an input field when clicking the delete action', async () => {
    const spy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value={['hello', 'goodbye', 'hola']}
        onDelete={spy}
      />
    )

    const button = container.querySelectorAll('.action-delete')[0]

    expect(container.querySelectorAll('input').length).toBe(3)

    user.click(button)

    await waitFor(() => {
      expect(container.querySelectorAll('input').length).toBe(2)

      // Check that "hello" was removed
      expect(spy).toHaveBeenCalledWith(
        expect.objectContaining({
          value: [
            expect.objectContaining({ value: 'goodbye' }),
            expect.objectContaining({ value: 'hola' }),
          ],
        })
      )
    })
  })

  test('should remove an input field when clicking the delete action (with options)', async () => {
    const spy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value={[
          { option: 'Work', value: 'work_phone', id: '' },
          { option: 'Home', value: 'home_phone', id: '' },
        ]}
        valueOptions={['Home', 'Work', 'Other']}
        defaultOption="Home"
        onDelete={spy}
      />
    )

    const button = container.querySelectorAll('.action-delete')[0]

    expect(container.querySelectorAll('input').length).toBe(2)

    user.click(button)

    await waitFor(() => {
      expect(container.querySelectorAll('input').length).toBe(1)

      // Check that "work" was removed
      expect(spy).toHaveBeenCalledWith(
        expect.objectContaining({
          value: [expect.objectContaining({ value: 'home_phone' })],
        })
      )
    })
  })
})

describe('Options', () => {
  test('render options when passed in', async () => {
    const { container, getAllByRole, getByRole, queryByRole } = render(
      <EditableField
        name="company"
        value={{ option: 'Work', value: '123456789', id: '' }}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )
    const button = container.querySelector(
      `.${INPUT_CLASSNAMES.optionsTrigger}`
    )

    expect(queryByRole('listbox')).toBe(null)

    user.click(button)

    await waitFor(() => {
      expect(getByRole('listbox')).toBeInTheDocument()
      expect(getAllByRole('option').length).toBe(3)
    })
  })

  test('Option text should be the one in the value', () => {
    const { container } = render(
      <EditableField
        name="company"
        value={{ option: 'Work', value: '123456789', id: '' }}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Work')
  })

  test('Option text should be the default with empty value', () => {
    const { container } = render(
      <EditableField
        name="company"
        defaultOption="Other"
        value=""
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Other')
  })

  test('Option text should be the default with empty value (obj case)', () => {
    const { container } = render(
      <EditableField
        name="company"
        defaultOption="Other"
        value={{ value: '123456789', id: '' }}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Other')
  })

  test('With no value option text should be the default option passed', () => {
    const { container } = render(
      <EditableField
        name="company"
        defaultOption="Other"
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Other')
  })

  test('With no value option text should be the first in the list', () => {
    const { container } = render(
      <EditableField name="company" valueOptions={['Home', 'Work', 'Other']} />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Home')
  })

  test('With no value option text should be default passed in', () => {
    const { container } = render(
      <EditableField
        name="company"
        defaultOption="Other"
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Other')
  })

  test('Change option text when clicking a dropdown item', async () => {
    const { getAllByRole, container } = render(
      <EditableField
        name="company"
        value={{ option: 'Work', value: '123456789', id: '' }}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    const button = container.querySelector(
      `.${INPUT_CLASSNAMES.optionsTrigger}`
    )

    user.click(button)
    user.click(getAllByRole('option')[0])

    await waitFor(() => {
      expect(
        container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`)
          .textContent
      ).toBe('Home')
    })
  })

  test('Should change a given value if passed on props with options', () => {
    const { container, rerender } = render(
      <EditableField
        name="company"
        value={{ option: 'Work', value: '11111', id: '001' }}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )
    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Work')

    rerender(
      <EditableField value={{ option: 'Home', value: '888888', id: '001' }} />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Home')
  })

  test('Should change a given value if passed on props with options (default option)', () => {
    const { container, rerender } = render(
      <EditableField
        name="company"
        defaultOption="Other"
        value={{ value: '11111', id: '001' }}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Other')

    rerender(
      <EditableField value={{ option: 'Home', value: '888888', id: '001' }} />
    )

    expect(
      container.querySelector(`.${INPUT_CLASSNAMES.selectedOption}`).textContent
    ).toBe('Home')
  })
})

describe('Static Value', () => {
  test('should render the placeholder if no value present', () => {
    const { container } = render(
      <EditableField name="company" placeholder="Add something" />
    )

    expect(
      container.querySelector(`.${MASK_CLASSNAMES.value}`).textContent
    ).toBe('Add something')
  })

  test('should render the value if present', () => {
    const { container } = render(
      <EditableField name="company" value="hello" placeholder="Add something" />
    )

    expect(
      container.querySelector(`.${MASK_CLASSNAMES.value}`).textContent
    ).toBe('hello')
  })

  test('should emphasize the value if emphasizeTopValue and multivalue enabled', () => {
    const { container } = render(
      <EditableField
        name="company"
        value={['hello', 'hola']}
        placeholder="Add something"
        emphasizeTopValue
      />
    )

    expect(container.querySelector('.is-emphasized').textContent).toBe('hello')
    expect(
      window.getComputedStyle(
        container.querySelector(`.${MASK_CLASSNAMES.value}`)
      ).fontWeight
    ).toBe('500')
  })

  test('should be on top if field not active', () => {
    const { container } = render(
      <EditableField name="company" value="hello" placeholder="Add something" />
    )

    expect(
      window.getComputedStyle(
        container.querySelector(`.${MASK_CLASSNAMES.component}`)
      ).zIndex
    ).toBe('2')
  })

  test('should be on bottom if field active', () => {
    const { container, getByLabelText } = render(
      <EditableField name="company" value="hello" placeholder="Add something" />
    )

    const input = getByLabelText('company')

    input.focus()

    expect(
      window.getComputedStyle(
        container.querySelector(`.${MASK_CLASSNAMES.component}`)
      ).zIndex
    ).toBe('1')
  })

  test('static option', () => {
    const { container, getAllByRole } = render(
      <EditableField
        name="company"
        value={{ option: 'Work', value: '123456789', id: '' }}
        valueOptions={['Home', 'Work', 'Other']}
      />
    )

    expect(
      container.querySelector(`.${MASK_CLASSNAMES.option}`).textContent
    ).toBe('Work')

    user.click(container.querySelector(`.${INPUT_CLASSNAMES.optionsTrigger}`))
    user.click(getAllByRole('option')[0])

    expect(
      container.querySelector(`.${MASK_CLASSNAMES.option}`).textContent
    ).toBe('Home')
  })
})

describe('Actions', () => {
  test('should render delete action by default', () => {
    const { container } = render(<EditableField name="company" value="hello" />)

    expect(
      container.querySelector(`.${ACTIONS_CLASSNAMES.actions}`)
    ).toBeTruthy()
    expect(container.querySelector('.action-delete')).toBeTruthy()
  })

  test('should not render delete action if null passed', () => {
    const { container } = render(
      <EditableField name="company" value="hello" actions={null} />
    )

    expect(container.querySelector('.action-delete')).toBeFalsy()
  })

  test('should render passed actions in props', () => {
    const { container } = render(
      <EditableField
        name="company"
        value="hello"
        actions={{
          name: 'link',
        }}
      />
    )

    expect(container.querySelector('.action-delete')).toBeTruthy()
    expect(container.querySelector('.action-link')).toBeTruthy()
  })

  test('should render passed actions in props (array)', () => {
    const { container } = render(
      <EditableField
        name="company"
        value="hello"
        actions={[
          {
            name: 'link',
          },
        ]}
      />
    )

    expect(container.querySelector('.action-delete')).toBeTruthy()
    expect(container.querySelector('.action-link')).toBeTruthy()
  })

  test('Custom delete action', () => {
    const deleteSpy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value="hello"
        actions={{
          name: 'delete',
          callback: deleteSpy,
        }}
      />
    )

    const deleteBtn = container.querySelector('.action-delete')

    user.click(deleteBtn)

    expect(deleteSpy).toHaveBeenCalled()
  })

  test('should call callback function in action', () => {
    const spy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value="hello"
        actions={{
          name: 'something',
          callback: spy,
        }}
      />
    )

    user.click(container.querySelector('.action-something'))

    expect(spy).toHaveBeenCalled()
  })
})

describe('disabled', () => {
  test('should put disabled attr on input', () => {
    const { container } = render(
      <EditableField
        name="company"
        value={[{ option: 'Work', value: '123456789', id: '' }]}
        valueOptions={['Home', 'Work', 'Other']}
        disabled
      />
    )

    expect(
      container.querySelector('input').getAttribute('disabled')
    ).toBeDefined()
  })

  test('should put disabled classname', () => {
    const { container } = render(
      <EditableField
        name="company"
        value={[{ option: 'Work', value: '123456789', id: '' }]}
        valueOptions={['Home', 'Work', 'Other']}
        disabled
      />
    )

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.fieldDisabled}`)
    ).toBeTruthy()
  })

  test('should not render actions', () => {
    const { container } = render(
      <EditableField
        name="company"
        value={[{ option: 'Work', value: '123456789', id: '' }]}
        valueOptions={['Home', 'Work', 'Other']}
        disabled
      />
    )

    expect(
      container.querySelector(`.${ACTIONS_CLASSNAMES.actions}`)
    ).toBeFalsy()
    expect(container.querySelector('.action-delete')).toBeFalsy()
  })

  test('should not render add button', () => {
    const { container } = render(
      <EditableField
        name="company"
        value={[{ option: 'Work', value: '123456789', id: '' }]}
        valueOptions={['Home', 'Work', 'Other']}
        disabled
      />
    )

    const button = container.querySelector(
      `.${EDITABLEFIELD_CLASSNAMES.addButton}`
    )
    expect(button).toBeFalsy()
  })

  test('dropdown trigger should be disabled', () => {
    const { container } = render(
      <EditableField
        name="company"
        value={[{ option: 'Work', value: '123456789', id: '' }]}
        valueOptions={['Home', 'Work', 'Other']}
        disabled
      />
    )

    expect(
      container
        .querySelector(`.${INPUT_CLASSNAMES.optionsTrigger}`)
        .getAttribute('disabled')
    ).toBeDefined()
  })
})

describe('Events', () => {
  test('onInputFocus', () => {
    const spy = jest.fn()
    const { container } = render(
      <EditableField name="company" onInputFocus={spy} />
    )

    const input = container.querySelector('input')

    input.focus()

    expect(spy).toHaveBeenCalled()
  })

  test('onInputBlur', () => {
    const spy = jest.fn()
    const { container } = render(
      <EditableField name="company" onInputBlur={spy} />
    )

    const input = container.querySelector('input')

    input.focus()
    input.blur()

    expect(spy).toHaveBeenCalled()
  })

  test('onChange', () => {
    const spy = jest.fn()

    const { container } = render(
      <EditableField name="company" onChange={spy} />
    )

    const input = container.querySelector('input')

    user.type(input, 'a')

    expect(spy).toHaveBeenCalled()
  })

  test('onAdd', () => {
    const spy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value={['hello', 'goodbye', 'hola']}
        onAdd={spy}
      />
    )

    const button = container.querySelector(
      `.${EDITABLEFIELD_CLASSNAMES.addButton}`
    )

    user.click(button)

    expect(spy).toHaveBeenCalled()
  })

  test('onAdd: empty', () => {
    const spy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value={[
          { id: 'hh_0', value: 'dd' },
          { id: 'hh_1', value: 'fff' },
          { id: 'hh_2', value: '' },
        ]}
        onAdd={spy}
      />
    )

    const button = container.querySelector(
      `.${EDITABLEFIELD_CLASSNAMES.addButton}`
    )

    user.click(button)

    expect(spy).not.toHaveBeenCalled()
  })

  test('Pressing escape', () => {
    const onEscapeSpy = jest.fn()
    const onDiscardSpy = jest.fn()
    const { getByLabelText } = render(
      <EditableField
        name="company"
        onEscape={onEscapeSpy}
        onDiscard={onDiscardSpy}
      />
    )

    user.type(getByLabelText('company'), '{esc}')

    expect(onEscapeSpy).toHaveBeenCalled()
    expect(onDiscardSpy).toHaveBeenCalled()
  })

  test('Delete or clear a value', () => {
    const onDeleteSpy = jest.fn()
    const onCommitSpy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value="hello"
        onDelete={onDeleteSpy}
        onCommit={onCommitSpy}
      />
    )

    const deleteBtn = container.querySelector('.action-delete')

    user.click(deleteBtn)

    expect(onDeleteSpy).toHaveBeenCalled()
    expect(onCommitSpy).toHaveBeenCalled()
  })

  test('Focus option', () => {
    const spy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value={{ option: 'Work', value: '123456789', id: '1' }}
        valueOptions={['Home', 'Work', 'Other']}
        onOptionFocus={spy}
      />
    )

    container.querySelector(`.${INPUT_CLASSNAMES.optionsTrigger}`).focus()

    expect(spy).toHaveBeenCalled()
  })

  test('Changing option', () => {
    const onOptionChangeSpy = jest.fn()
    const onChangeSpy = jest.fn()
    const onCommitSpy = jest.fn()

    const { container, getAllByRole } = render(
      <EditableField
        name="company"
        value={{ option: 'Work', value: '123456789', id: '' }}
        valueOptions={['Home', 'Work', 'Other']}
        onOptionChange={onOptionChangeSpy}
        onChange={onChangeSpy}
        onCommit={onCommitSpy}
      />
    )

    user.click(container.querySelector(`.${INPUT_CLASSNAMES.optionsTrigger}`))
    user.click(getAllByRole('option')[0])

    expect(onOptionChangeSpy).toHaveBeenCalled()
    expect(onChangeSpy).toHaveBeenCalled()
    expect(onCommitSpy).toHaveBeenCalled()
  })
})

describe('enter press', () => {
  test('Pressing Enter: should not commit if value unchanged', () => {
    const onEnterSpy = jest.fn()
    const onCommitSpy = jest.fn()
    const wrapper = mount(
      <EditableField
        name="company"
        value={{ value: '1234567', id: '1' }}
        onEnter={onEnterSpy}
        onCommit={onCommitSpy}
      />
    )

    const input = wrapper.find('input').first()

    input.getDOMNode().value = '1234567'

    input.simulate('keydown', { key: 'Enter' })

    expect(onEnterSpy).toHaveBeenCalled()
    expect(onCommitSpy).not.toHaveBeenCalled()
  })

  test('Pressing Enter: should not commit if value invalid', done => {
    const onEnterSpy = jest.fn()
    const onCommitSpy = jest.fn()
    const wrapper = mount(
      <EditableField
        name="company"
        value={{ value: '1234567', id: '1' }}
        onEnter={onEnterSpy}
        onCommit={onCommitSpy}
        validate={({ name, value }) =>
          Promise.resolve({
            isValid: false,
            name,
            value,
            type: 'error',
            message: 'That is definitely not right',
          })
        }
      />
    )

    const input = wrapper.find('input').first()

    input.getDOMNode().value = '8888'

    input.simulate('keydown', { key: 'Enter' })

    const f = flushPromises()
    jest.runAllTimers()

    f.then(() => {
      expect(onEnterSpy).toHaveBeenCalled()
      expect(onCommitSpy).not.toHaveBeenCalled()
      done()
    }).catch(done)
  })

  test('Pressing Enter: should not commit if value empty', () => {
    const onEnterSpy = jest.fn()
    const onCommitSpy = jest.fn()
    const wrapper = mount(
      <EditableField
        name="company"
        multipleValues
        value="hello"
        onEnter={onEnterSpy}
        onCommit={onCommitSpy}
      />
    )

    const input = wrapper.find('input').first()

    input.getDOMNode().value = ''

    input.simulate('keydown', { key: 'Enter' })

    expect(onCommitSpy).not.toHaveBeenCalled()
  })

  test('Pressing Enter: should commit if value changes', () => {
    const onEnterSpy = jest.fn()
    const onCommitSpy = jest.fn()
    const wrapper = mount(
      <EditableField
        name="company"
        value={{ value: '1234567', id: '1' }}
        onEnter={onEnterSpy}
        onCommit={onCommitSpy}
      />
    )

    const input = wrapper.find('input').first()

    input.getDOMNode().value = '123'
    input.simulate('keydown', { key: 'Enter' })

    flushPromises().then(() => {
      wrapper.update()

      expect(onEnterSpy).toHaveBeenCalled()
      expect(onCommitSpy).toHaveBeenCalled()
    })
  })

  test('Pressing Enter: should update props on validation resolved', done => {
    const wrapper = mount(
      <EditableField
        name="company"
        value={{ value: '123456', id: '1' }}
        validate={({ name, value }) =>
          Promise.resolve({
            isValid: true,
            name: 'company',
            type: 'default',
            updatedProps: { _id: 7 },
            value: '123',
          })
        }
      />
    )
    const input = wrapper.find('input').first()

    input.getDOMNode().value = '123'
    input.simulate('keydown', { key: 'Enter' })

    const f = flushPromises()
    jest.runAllTimers()

    f.then(() => {
      expect(wrapper.state('fieldValue')).toEqual([
        {
          _id: 7,
          id: '1',
          validated: true,
          value: '123',
        },
      ])
      done()
    }).catch(done)
  })

  test('Pressing Enter: should update props on validation resolved', () => {
    const wrapper = mount(
      <EditableField
        name="company"
        value={{ value: '123456', id: '1' }}
        validate={({ name, value }) =>
          Promise.resolve({
            isValid: true,
            name: 'company',
            type: 'default',
            updatedProps: { _id: 7 },
            value: '123',
          })
        }
      />
    )
    const input = wrapper.find('input').first()

    input.getDOMNode().value = '123'
    input.simulate('keydown', { key: 'Enter' })

    const f = flushPromises()

    f.then(d => {
      expect(wrapper.state('value')).toEqual('123')
      expect(wrapper.state('_id')).toEqual(7)
    }).catch(e => {
      // console.log('HS: e', e)
    })
  })
})

describe('should component update', () => {
  test('value', () => {
    const wrapper = mount(<EditableField name="greeting" value="hello" />)
    const actualProps = wrapper.props()
    const actualState = wrapper.state()
    const newPropsSame = {
      ...actualProps,
      value: 'hello',
    }
    const newPropsChanged = {
      ...actualProps,
      value: 'hola',
    }

    expect(
      wrapper.instance().shouldComponentUpdate(newPropsSame, actualState)
    ).toBeFalsy()

    expect(
      wrapper.instance().shouldComponentUpdate(newPropsChanged, actualState)
    ).toBeTruthy()
  })

  test('fieldValue', () => {
    const val = {
      value: 'hello',
      id: 'greeting_0',
    }
    const wrapper = mount(<EditableField name="greeting" value={val} />)
    const actualProps = wrapper.props()
    const actualState = wrapper.state()
    const newStateSame = {
      ...actualState,
    }
    const newStateChanged = {
      fieldValue: [],
    }

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateSame)
    ).toBeFalsy()

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateChanged)
    ).toBeTruthy()
  })

  test('disabled', () => {
    const wrapper = mount(
      <EditableField name="greeting" value="hello" disabled />
    )
    const actualProps = wrapper.props()
    const actualState = wrapper.state()
    const newPropsSame = {
      ...actualProps,
    }
    const newPropsChanged = {
      ...actualProps,
      disabled: false,
    }

    expect(
      wrapper.instance().shouldComponentUpdate(newPropsSame, actualState)
    ).toBeFalsy()

    expect(
      wrapper.instance().shouldComponentUpdate(newPropsChanged, actualState)
    ).toBeTruthy()
  })

  test('activeField', () => {
    const val = {
      value: 'hello',
      id: 'greeting_0',
    }
    const wrapper = mount(<EditableField name="greeting" value={val} />)
    const actualProps = wrapper.props()
    const actualState = wrapper.state()
    const newStateSame = {
      ...actualState,
    }
    const newStateChanged = {
      activeField: 'something',
    }

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateSame)
    ).toBeFalsy()

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateChanged)
    ).toBeTruthy()
  })

  test('mask tab index', () => {
    const val = {
      value: 'hello',
      id: 'greeting_0',
    }
    const wrapper = mount(<EditableField name="greeting" value={val} />)
    const actualProps = wrapper.props()
    const actualState = wrapper.state()
    const newStateSame = {
      ...actualState,
    }
    const newStateChanged = {
      maskTabIndex: 'something',
    }

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateSame)
    ).toBeFalsy()

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateChanged)
    ).toBeTruthy()
  })

  test('disabledItem', () => {
    const val = {
      value: 'hello',
      id: 'greeting_0',
    }
    const wrapper = mount(<EditableField name="greeting" value={val} />)
    const actualProps = wrapper.props()
    const actualState = wrapper.state()
    const newStateSame = {
      ...actualState,
    }
    const newStateChanged = {
      disabledItem: ['something'],
    }

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateSame)
    ).toBeFalsy()

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateChanged)
    ).toBeTruthy()
  })

  test('validationInfo', () => {
    const validationInfo = {
      isValid: false,
      name: 'email',
      value: 'hello',
      type: 'error',
    }
    const val = {
      value: 'hello',
      id: 'greeting_0',
    }
    const wrapper = mount(<EditableField name="greeting" value={val} />)
    const actualProps = wrapper.props()
    const actualState = wrapper.state()
    const newStateSame = {
      ...actualState,
    }
    const newStateChanged = {
      validationInfo,
    }

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateSame)
    ).toBeFalsy()

    expect(
      wrapper.instance().shouldComponentUpdate(actualProps, newStateChanged)
    ).toBeTruthy()
  })
})

describe('Input Blur', () => {
  test('If unchanged, it should deactivate the field and leave as', () => {
    const blurSpy = jest.fn()
    const { container, getByLabelText } = render(
      <EditableField name="company" value="hello" onInputBlur={blurSpy} />
    )
    const input = getByLabelText('company')

    input.focus()

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
    ).toBeTruthy()

    user.clear(input)
    user.type(input, 'hello')
    input.blur()

    expect(input.value).toBe('hello')
    expect(
      container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
    ).toBeFalsy()
    expect(blurSpy).toHaveBeenCalled()
  })

  test('If value cleared in single value case, it should deactivate the field and leave as', async () => {
    const commitSpy = jest.fn()
    const blurSpy = jest.fn()

    const { container, getByLabelText } = render(
      <EditableField
        name="company"
        value="hello"
        onCommit={commitSpy}
        onInputBlur={blurSpy}
      />
    )

    const input = getByLabelText('company')

    input.focus()

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
    ).toBeTruthy()

    user.clear(input)
    input.blur()

    await waitFor(() => {
      expect(
        container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
      ).toBeFalsy()
      expect(commitSpy).toHaveBeenCalled()
      expect(blurSpy).toHaveBeenCalled()
    })
  })

  test('If value cleared in multivalue, it should deactivate the field and remove', async () => {
    const commitSpy = jest.fn()
    const blurSpy = jest.fn()
    const discardSpy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value={['hello', 'hola']}
        onCommit={commitSpy}
        onInputBlur={blurSpy}
        onDiscard={discardSpy}
      />
    )

    const input = container.querySelectorAll('input')[0]

    input.focus()

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
    ).toBeTruthy()
    expect(container.querySelectorAll('input').length).toBe(2)

    user.clear(input)
    input.blur()

    await waitFor(() => {
      expect(
        container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
      ).toBeFalsy()
      expect(container.querySelectorAll('input').length).toBe(1)
      expect(commitSpy).toHaveBeenCalled()
      expect(blurSpy).toHaveBeenCalled()
      expect(discardSpy).toHaveBeenCalled()
    })
  })

  test('If value cleared in multivalue, it should not remove the only field left', async () => {
    const commitSpy = jest.fn()
    const blurSpy = jest.fn()
    const discardSpy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value={['hello']}
        onCommit={commitSpy}
        onInputBlur={blurSpy}
        onDiscard={discardSpy}
      />
    )

    const input = container.querySelectorAll('input')[0]

    input.focus()

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
    ).toBeTruthy()
    expect(container.querySelectorAll('input').length).toBe(1)

    user.clear(input)
    input.blur()

    await waitFor(() => {
      expect(
        container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
      ).toBeFalsy()
      expect(container.querySelectorAll('input').length).toBe(1)
      expect(commitSpy).toHaveBeenCalled()
      expect(blurSpy).toHaveBeenCalled()
    })
  })

  test('If value changed and valid, it should commit', async () => {
    const commitSpy = jest.fn()
    const blurSpy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value="hello"
        onCommit={commitSpy}
        onInputBlur={blurSpy}
      />
    )

    const input = container.querySelector('input')

    input.focus()

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
    ).toBeTruthy()

    user.clear(input)
    user.type(input, 'hola')
    input.blur()

    await waitFor(() => {
      expect(input.value).toBe('hola')
      expect(
        container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
      ).toBeFalsy()
      expect(commitSpy).toHaveBeenCalled()
      expect(blurSpy).toHaveBeenCalled()
    })
  })

  test('If value changed and invalid, it should not commit', async () => {
    const commitSpy = jest.fn()
    const blurSpy = jest.fn()

    const { container } = render(
      <EditableField
        name="company"
        value="hello"
        onCommit={commitSpy}
        onInputBlur={blurSpy}
        validate={({ name, value }) =>
          Promise.resolve({
            isValid: false,
            name,
            value,
            type: 'error',
            message: 'That is definitely not right',
          })
        }
      />
    )

    const input = container.querySelector('input')

    input.focus()

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.isActive}`)
    ).toBeTruthy()

    user.clear(input)
    user.type(input, 'hola')
    input.blur()

    await waitFor(() => {
      expect(input.value).toBe('hola')
      expect(commitSpy).not.toHaveBeenCalled()
      expect(blurSpy).toHaveBeenCalled()
    })
  })

  test('Input blur: should update props on validation resolved', done => {
    const wrapper = mount(
      <EditableField
        name="company"
        value={{ value: '', id: '1' }}
        validate={() => {
          return Promise.resolve({
            isValid: true,
            name: 'company',
            type: 'default',
            updatedProps: { _id: 7 },
            value: '1234567',
          })
        }}
      />
    )
    const input = wrapper.find('input').first()
    input.simulate('focus')

    wrapper.instance().handleInputChange({ name: '1', inputValue: '1234567' })

    input.simulate('blur')
    const f = flushPromises()
    jest.runAllTimers()
    f.then(() => {
      expect(wrapper.state('fieldValue')).toEqual([
        {
          _id: 7,
          id: '1',
          validated: true,
          value: '1234567',
        },
      ])
      done()
    }).catch(done)
  })
})

describe('floating labels', () => {
  test('Adds the floating labels className', () => {
    const { container } = render(
      <EditableField name="company" floatingLabels />
    )

    expect(
      container.querySelector(`.${STATES_CLASSNAMES.withFloatingLabels}`)
    ).toBeTruthy()
  })

  test('Label is hidden when floating labels on', () => {
    const { container } = render(
      <EditableField name="company" floatingLabels />
    )

    const el = container.querySelector(`.${EDITABLEFIELD_CLASSNAMES.label}`)

    expect(el).toBeFalsy()
  })
})

redpajama_set_name: RedPajamaGithub


text:
Home Diplomacy 'Turkey determined and able to protect its own rights'
'Turkey determined and able to protect its own rights'
Trying to test Turkey's power would be unwise, said the nation's defense minister on Thursday, reiterating that it is both determined and able to protect its own rights and interests.
Everyone should know that the Turkish Republic has truly become a player on the international stage, Hulusi Akar told Anadolu Agency's Editors' Desk.
Akar spoke on a range of issues, including Turkey's rising international profile and its stance on tensions in the Eastern Mediterranean.
The Navtex maritime alert Turkey issued on Sunday was to ensure the safety of its naval forces in the Eastern Mediterranean during a training off the coast of Iskenderun, southern Turkey, said Akar.
Greece had criticized the alert and the next day issued a competing Navtex for maritime drills, in the process raising tension in the region.
On disputes over maritime boundaries in the Eastern Mediterranean, Akar stressed that Turkey has no designs on anyone's land or sea, but the country will not allow any attack on its territory from its neighbors' lands or seas.
On Turkey's borders in the Eastern Mediterranean, he explained: "We said what would happen if you violated them. But we always stress that we favor dialogue."
Against Greece's "maximalist" maritime claims, trying to confine Turkey to shore based on small Greek islands just off the Turkish coast, Turkey has sought dialogue to reach fair sharing through a win-win approach.
Turkey would welcome Greek officials seeking dialogue
"Turkey favors dialogue [on maritime issues], we want peace, but we also want our rights," said Akar, stressing Turkey's desire for dialogue.
Turkey would be happy to welcome its Greek counterparts if they decide to sit down and talk, he added.
"Turkey's power should not be tested," said Akar, reiterating that Turkey is determined and able to protect its own rights and interests.
Dialogue over the Eastern Mediterranean should be the first option, otherwise undesirable situations could follow, he cautioned.
Turkey has consistently opposed Greek efforts to declare a huge exclusive economic zone, violating the interests of Turkey, the country with the longest coastline in the Mediterranean.
Ankara has also said energy resources near the island of Cyprus must be shared fairly between the Turkish Republic of Northern Cyprus (TRNC) – which has issued Turkish state oil company Turkish Petroleum a license – and the Greek Cypriot administration of Southern Cyprus.
French claim ship was harassed
"France's claims that Turkey harassed a French ship were proven false. France should apologize to the Turkish Republic," Akar said, referring to an incident this June near Libya.
Turkey said a NATO investigation of the incident proved its ships did nothing wrong.
Ankara has opposed French interference in the Mediterranean, including its support for Libyan warlord Khalifa Haftar and favoring Greece's expansive maritime claims.
Turkey expects France to act in line with reason and law in the region, he added.
Turning to Turkey's activities in Libya, Akar said: "Turkey is pursuing humanitarian and other activities in line with international law, and will continue doing so."
Last November, Turkey and Libya signed pacts on security cooperation and maritime boundaries.
Following the ouster of late ruler Muammar Gaddafi in 2011, Libya's new government was founded in 2015 under a political deal led by the UN.
Libya's internationally recognized government has been under attack by warlord Haftar's forces since April 2019, with more than 1,000 killed in the violence.
With Turkish support, Libya's government has recently turned the tide against the forces of Haftar, while stressing that there is no military solution for Libya.
Turkey's fight with terrorism
"Turkey has neutralized 17,200 terrorists since July 2015," said Akar.
Turkey's only target is the terrorists, he added.
Turkey has launched several counter-terrorist military operations in recent years, especially against the YPG/PKK, which has tried to use northern Iraq and northern Syria as cross-border terrorist bases against Turkey.
In its more than 30-year terror campaign against Turkey, the PKK – listed as a terrorist organization by Turkey, the US and the European Union – has been responsible for the deaths of nearly 40,000 people, including women, children, and infants. The YPG is the PKK's Syrian branch.
Turkish Military
Previous articleZimbabwe's open-air churches fueling spread of COVID-19
Next articleUS crude oil inventories fall for week ending Aug. 21
Turkish, Senegalese defense chiefs sign Military Framework Agreement
Turkey's defense chief inspects military post along Syrian border
Turkish president vows to end dependence on foreign defense goods
Turkey: Top defense officials visit anti-terror op zone
Martyred corps commander remembered for FETO fight
Probe ongoing into Turkish military helicopter crash
Israeli envoy hints at 'improvement' for Turkey ties
Russia, Turkey implement Syria deal 'with all terms'
Turkiye says it will continue to stand by Palestine for independent...

redpajama_set_name: RedPajamaCommonCrawl


Are you addicted to Netflix? And Don't want to miss the latest TV Series. Now, We will share the fully working Netflix MOD APK Premium latest version for Movies/Series lovers.Generally, It is giving 30 day Free Premium trial for the users. After that, you should pay to them for enjoying uninterrupted services. The prices are ranging from $7.99 to $16.99.These are based on the screens that you want and Resolution. Only you can get Ultra HD 4K Resolution content in Ultra and Premium plan. If you are that kind of person who always thinks budget-friendly, then go with the basic plan $7.99 one.
1-month free Netflix membership offer is available to first-time and certain former members and cannot be combined with any other offer. Internet access and valid payment method are required to redeem offer. Netflix will begin to bill your payment method for the Netflix membership fee at the end of the free month unless you cancel prior to the end of the first month. Your Netflix membership is a month-to-month subscription that you can cancel at any time. Go to "Your Account" on the Netflix website for cancellation instructions. No refund or credit for partial monthly subscription periods. A device that streams from Netflix (manufactured and sold separately) and broadband internet connection are required to watch instantly.
But, If you are a type of human being like me, then what we will actually do? We Just open a browser and search for Netflix MOD APK. That's a simple technique we use.
However, We are always looking for this kind of mod apks to get the benefits for free. Isn't it?
Well, we are here for you to provide awesome mod applications without showing a bunch of popup ads on our site.
Below you will find the Netflix MOD APK Premium download link. Just Scroll down a bit.
The American Entertainment company Co-founded by Reed Hastings and Marc Randolph. Now, it is a world-leading video streaming service with over 130 Million Subscribers.It is Subscription-based video streaming service which is popular with its TV Series Originals. Particularly people would like to buy its subscription for its TV Episodes.That much impact we get once we start using Netflix Originals. If you are already addicted to any one of the TV Series, then you have to spend money on the subscription.Or else, you can simply download our Netflix Mod APK Premium for watching videos for free of Cost.
Below are some cool features that you should know before downloading.
Yep, you heard it right. It is totally free to use without providing any login information or anything. So, I hope this Netflix MOD APK Premium lets you enjoy your weekend.
All you need is; install the Application in the right manner by following our installation steps. That's simple.
No one likes the Advertisement in-between the Video Content. This could be the best alternative for those who bothered with the advertisements.
Basically, the maximum 2k resolution is enough for watching videos in detail as per me on a Mobile device. If you are high-end smartphone user and have a bunch of mobile data, then you can enjoy up to 4k Video Content for free.
For 4K televisions, this much resolution is mandatory to feel the content.
Well, I am glad that you finally find out the download section of Netflix MOD APK Premium. It just a simple process to get that on your android device.
Meanwhile, there is a perfect alternative for this app too. It is named Showbox and aiming to provide TV Series/Movies for free. Anyway, coming to our download thing.
Are you eagerly waiting for the download link?


text:
Guy Ritchie taught Charlie Hunnam jiu-jitsu
ICONINSIDER — Guy Ritchie taught Charlie Hunnam jiu-jitsu.
The 36-year-old actor worked with the director on the upcoming adventure movie 'King Arthur: Legend of the Sword' and has said the 48-year-old filmmaker taught him the basics of the Japanese martial art whilst on set for the feature.
Charlie said during an appearance on 'The Late Late Show with James Corden' on Wednesday (05.04.17): "I did a film with Guy Ritchie about 18 months ago, who is a black belt in jiu-jitsu so I got into doing a little bit of jiu-jits with ol' Ritchie. That's right my friend."
And when show host James Corden asked 'Pacific Rim' actor if he decided to take up the fighting style just because Guy had, Charlie admitted the pair had a "roll around" on set.
He added: "Yeah. He likes to stay active on set and you know, just keep things fun, so we'd have ourselves a little roll around."
Despite getting on so well with the filmmaker, Charlie recently admitted it isn't easy for him to bond with everyone on set as during filming for the recently released action movie 'The Lost City of Z', he felt "a real distance" between him and his co-star Robert Pattinson.
Charlie said: "I had a couple of rehearsal sessions with Sienna [Miller], but I didn't spend any time with Tom [Holland] or Robert.
"I wanted these relationships to evolve naturally on screen. Through the work, I don't think I said more than ten words to Robert off camera. I didn't know if he was just 'in that zone' or if he genuinely didn't like me. There was a real distance between us."
Although he was concerned Robert, 30, wouldn't like him, the 'Sons of Anarchy' actor admits the cold attitude helped create "the right dynamic on screen" between Rob's Henry Costin and Charlie's Percy Fawcett.
And now that filming has long since wrapped on the production, Charlie says things are looking up for their friendship.
He added: "He's reached out to me subsequently, making overtures for us to be friends now so I think it was about the work."


text:
Си́ла тя́жести — сила, действующая на любое физическое тело вблизи поверхности астрономического объекта (планеты, звезды) и складывающаяся из силы гравитационного притяжения этого объекта и центробежной силы инерции, вызванной его суточным вращением.

Прочие приложенные к телу силы — такие как силы Кориолиса при движении тела по поверхности планеты и Архимеда при наличии атмосферы или жидкости — в силу тяжести не включаются.

В большинстве практических случаев анализируется сила тяжести вблизи Земли. Для неё величина центробежной силы составляет доли процента от величины гравитационной и иногда игнорируется.

Сила тяжести , действующая на материальную точку массой , вычисляется по формуле
 ,
где  — ускорение свободного падения. Сила тяжести является консервативной. Она сообщает любому телу, независимо от его массы, ускорение . Значение  диктуется параметрами (массой , размерами, скоростью вращения ) планеты или звезды и координатами на её поверхности.

Если в пределах протяжённого тела поле тяжести приблизительно однородно, то равнодействующая сил тяжести, действующих на элементы этого тела, приложена к центру масс тела.

В нерусскоязычной литературе термин «сила тяжести» не вводится — вместо этого говорят о фундаментальном гравитационном взаимодействии, при необходимости делая уточнение о центробежной добавке.

История
Личности, внёсшие исторический вклад в развитие представлений о силе тяжести:

Аристотель объяснял силу тяжести движением тяжёлых физических стихий (земля, вода) к своему естественному месту (центру Вселенной внутри Земли), причём скорость тем больше, чем ближе тяжёлое тело к нему.

Архимед рассмотрел вопрос о центре тяжести параллелограмма, треугольника, трапеции и параболического сегмента. В сочинении «О плавающих телах» Архимед доказал закон гидростатики, носящий его имя.

Иордан Неморарий в сочинении «О тяжестях» при рассмотрении грузов на наклонной плоскости разлагал их силы тяжести на нормальную и параллельную наклонной плоскости составляющие, был близок к определению статического момента.

Стевин экспериментально определил, что тела разных масс падают с одинаковым ускорением, установил теоремы о давлении жидкости в сосудах (давление зависит только от глубины и не зависит от величины, формы и объёма сосуда) и о равновесии грузов на наклонной плоскости (на наклонных плоскостях равной высоты силы, действующие со стороны уравновешивающихся грузов вдоль наклонных плоскостей, обратно пропорциональны длинам этих плоскостей). Доказал теорему, согласно которой в случае равновесия центр тяжести однородного плавающего тела должен находиться выше центра тяжести вытесненной жидкости.

Галилей экспериментально исследовал законы падения тел (ускорение не зависит от веса тела), колебаний маятников (период колебаний не зависит от веса маятника) и движения по наклонной плоскости.

Гюйгенс создал классическую теорию движения маятника, оказавшую значительное влияние на теорию тяготения.

Декарт разработал кинетическую теорию тяготения, объяснявшую силу тяжести взаимодействием тел с небесным флюидом, выдвинул гипотезу о зависимости силы тяжести от расстояния между тяжёлым телом и центром Земли.

Ньютон из равенства ускорений падающих тел и второго закона Ньютона сделал вывод о пропорциональности силы тяжести массам тел и установил, что сила тяжести является одним из проявлений силы всемирного тяготения. Для проверки этой идеи он сравнил ускорение свободного падения тел у поверхности Земли с ускорением Луны на орбите, по которой она движется относительно Земли.

Эйнштейн объяснил факт равенства ускорений падающих тел независимо от их массы (эквивалентность инертной и тяжёлой массы)
как следствие принципа эквивалентности равномерно ускоренной системы отсчёта и системы отсчёта, находящейся в гравитационном поле.

Сила тяжести в различных ситуациях

Сферически симметричный небесный объект
В соответствии с законом всемирного тяготения, модуль силы гравитационного притяжения , действующей на материальную точку на поверхности астрономического объекта со сферически симметричным распределением массы по объёму, определяется соотношением
 ,
где  — гравитационная постоянная, равная 6,67384(80)·10−11 м3·с−2·кг−1,  — радиус астрономического тела,  — его масса,  — масса материальной точки. Сила гравитационного притяжения направлена к центру тела.

Модуль центробежной силы инерции , действующей на материальную точку, задаётся формулой
 ,
где  — расстояние между частицей и осью вращения рассматриваемого астрономического объекта,  — угловая скорость его вращения. Центробежная сила инерции перпендикулярна оси и направлена от неё.

Сила тяжести вычисляется по теореме косинусов:
 .
Здесь  — «широта» места на планете или звезде, для которого производится расчёт.

Планеты Солнечной системы в шаровом приближении
Приближённо, Солнце и планеты Солнечной системы можно рассматривать как сферически симметричные астрономические объекты, а при грубом вычислении  брать широту  = 450 («посредине»). Сравнение силы тяжести, оцененной в таком приближении, на поверхностях ряда планет представлено в таблице. За единицу принята сила тяжести на Земле.

В условиях Земли и других планет, поправки, вносимые общей теорией относительности в закон всемирного тяготения, крайне малы (модуль гравитационного потенциала на поверхности Земли, равный половине квадрата второй космической скорости , крайне мал по сравнению с квадратом скорости света: ).

Планета Земля с учётом особенностей её формы
Форма Земли (геоид) отличается от строго шарообразной и близка к сплюснутому эллипсоиду.

Соответственно, в более точном, чем шаровое, приближении, сила гравитационного притяжения, действующая на материальную точку массой , определяется выражением
 ,
где  — элемент массы Земли ( — плотность),  и  — радиус-векторы точки измерения и элемента массы Земли соответственно. Интегрирование выполняется по всему объёму Земли.

В векторной форме выражение для центробежной силы инерции можно записать в виде
 ,
где  — вектор, перпендикулярный оси вращения и проведённый от неё к точке измерения.

Сила тяжести является суммой  и :

Сила тяжести вблизи поверхности Земли зависит от широты места  и высоты  над уровнем моря. Широтное изменение  связано как с отклонением формы Земли от шарообразной, так и с наличием центробежной силы. Приблизительное выражение для абсолютной величины силы тяжести в системе СИ имеет вид

Угол  между силой тяжести  и силой гравитационного притяжения к Земле  равен:

 .

Он изменяется в пределах от нуля (на экваторе, где  и на полюсах, где ) до  рад или  (на широте ).

Дополнительно, можно учесть эффект притяжения Луны и Солнца (искусственно введя временные изменения гравитационного поля Земли, то есть добавки к ), несмотря на его малость.

Статика и динамика тела в поле тяжести Земли

Устойчивость тела в поле силы тяжести
Для тела в поле силы тяжести, опирающегося на одну точку (например при подвешивании тела за одну точку или помещении шара на плоскость) для устойчивого равновесия необходимо, чтобы центр тяжести тела занимал наинизшее положение по сравнению со всеми возможными соседними положениями.

Для тела в поле силы тяжести, опирающегося на несколько точек (например, стол) или на целую площадку (например, ящик на горизонтальной плоскости) для устойчивого равновесия необходимо, чтобы вертикаль, проведённая через центр тяжести, проходила внутри площади опоры тела. Площадью опоры тела называется контур, соединяющий точки опоры или внутри площадки, на которую опирается тело.

Потенциальная энергия поднятого над Землёй тела
Потенциальная энергия поднятого над Землёй тела может быть найдена как взятая с обратным знаком работа силы тяжести при перемещении тела с поверхности Земли в данное положение. Если пренебречь центробежной силой и считать Землю шаром, эта энергия равна:

 ,

где  — гравитационная постоянная,  — масса Земли,  — масса тела,  — радиус Земли,  — расстояние от тела до центра Земли.

При удалении тела от поверхности Земли не небольшие, по сравнению с , расстояния поле тяготения можно считать однородным, а ускорение свободного падения постоянным. В этом случае при подъёме тела массой  на высоту  от поверхности Земли сила тяжести совершает работу . Поэтому потенциальная энергия тела составляет , если за нуль энергии взята энергия на поверхности планеты. Тело, находящееся на глубине  от поверхности Земли, обладает отрицательным значением потенциальной энергии .

Движение тел под действием силы тяжести Земли
В случае, когда модуль перемещения тела много меньше расстояния до центра Земли, можно считать силу тяжести постоянной, а движение тела равноускоренным. Если начальная скорость тела отлична от нуля и её вектор направлен не по вертикали, то под действием силы тяжести тело движется по параболической траектории.

При бросании тела с некоторой высоты параллельно поверхности Земли дальность полёта увеличивается с ростом начальной скорости. При больших значениях начальной скорости для вычисления траектории тела необходимо учитывать шарообразную форму Земли и изменение направления силы тяжести в разных точках траектории.

При некотором значении скорости, называемом первой космической скоростью, тело, брошенное по касательной к поверхности Земли, под действием силы тяжести при отсутствии сопротивления со стороны атмосферы может двигаться вокруг Земли по окружности, не падая на Землю. При скорости, превышающую вторую космическую скорость, тело уходит от поверхности Земли в бесконечность по гиперболической траектории. При скоростях, промежуточных между первой и второй космическими, тело движется вокруг Земли по эллиптической траектории.

Глобальная роль силы тяжести в природе

В эволюции строения планет и звёзд
Сила тяжести играет огромную роль в процессах эволюции звёзд. Для звёзд, находящихся на этапе главной последовательности своей эволюции, сила тяжести является одним из важных факторов, обеспечивающих условия, необходимые для термоядерного синтеза. На заключительных этапах эволюции звёзд, в процессе их коллапса, благодаря силе тяжести, не скомпенсированной силами внутреннего давления, звёзды превращаются в нейтронные звёзды или чёрные дыры.

Сила тяжести важна для формирования внутренней структуры планет, включая Землю, и тектонической эволюции их поверхностей. Чем больше сила тяжести, тем большая масса метеоритного материала выпадает на единицу поверхности планеты. За время существования Земли её масса существенно увеличилась благодаря силе тяжести: ежегодно на Землю оседает 30-40 млн тонн метеоритного вещества, в основном в виде пыли, что значительно превышает рассеяние лёгких компонентов верхней атмосферы Земли в космосе.

Потенциальная энергия перемещаемых тектоническими процессами масс горных пород тратится на перемещение продуктов разрушения горных пород с повышенных участков поверхности на нижерасположенные.

В создании условий для жизни на Земле
Сила тяжести чрезвычайно значима для жизни на Земле. Только благодаря ей у Земли есть атмосфера. Вследствие силы тяжести, действующей на воздух, существует атмосферное давление.

Без потенциальной энергии силы тяжести, непрерывно переходящей в кинетическую, круговорот вещества и энергии на Земле был бы невозможен.

При испарении воды с поверхности Земли энергия солнечной радиации трансформируется в потенциальную энергию водяного пара в атмосфере. Затем при выпадении атмосферных осадков на сушу она переходит при стоке в кинетическую энергию и совершает эрозионную работу в процессе переноса денудационного материала всей суши и делает возможным жизнь органического мира на Земле.

У всех живых организмов с нервной системой есть рецепторы, определяющие величину и направление силы тяжести и служащие для ориентировки в пространстве. У позвоночных организмов, в том числе человека, величину и направление силы тяжести определяет вестибулярный аппарат.

Наличие силы тяжести привело к возникновению у всех многоклеточных наземных организмов прочных скелетов, необходимых для её преодоления. У водных живых организмов силу тяжести уравновешивает гидростатическая сила.

Роль силы тяжести в процессах жизнедеятельности организмов изучает гравитационная биология.

Применение силы тяжести Земли в технике
Сила тяжести и принцип эквивалентности инертной и гравитационной массы используются для определения масс предметов путём их взвешивания на весах. Сила тяжести используется при отстойной сепарации газовых и жидких смесей, в процессах гравитационного обогащения полезных ископаемых, в некоторых типах часов, в отвесах и противовесах, машине Атвуда, машине Обербека и жидкостных барометрах. Сила тяжести используется на железнодорожном транспорте для скатывания вагонов с уклона на сортировочных горках, на заводах строительных изделий для транспортировки материалов в спускных лотках и спускных трубах.

Точные измерения силы тяжести и её градиента (гравиметрия) используются при исследовании внутреннего строения Земли и при гравиразведке различных полезных ископаемых.

Методы измерения силы тяжести

Силу тяжести измеряют динамическими и статическими методами. Динамические методы используют наблюдение за движением тела под действием силы тяжести и измеряют время перехода тела из одного заранее определённого положения в другое. Они используют: колебания маятника, свободное падение тела, колебания струны с грузом. Статические методы используют наблюдение за изменением положения равновесия тела под действием силы тяжести и некоторой уравновешивающей её силы и измеряют линейное или угловое смещение тела.

Измерения силы тяжести бывают абсолютными и относительными. Абсолютные измерения определяют полное значение силы тяжести в заданной точке. Относительные измерения определяют разность силы тяжести в заданной точке и некоторого другого, заранее известного значения. Приборы, предназначенные для относительных измерений силы тяжести, называются гравиметрами.

Динамические методы определения силы тяжести могут быть как относительными, так и абсолютными, статические — только относительными.

См. также
 Вес
 Ускорение свободного падения
 Гравиметрия (геодезия)

Примечания

Литература

Гравитация
тяжести

redpajama_set_name: RedPajamaWikipedia


text:
History & Shared Values
Processes We Support >
Processes We Support
P&D Platform >
P&D Platform
P&D Platform Facebook
Children and War
Healing and Reconciliation
Music4Peace
Blog - Culture of Peace
Our Mission, Approach,
Structure and Programs
Photo: A Dialogue Table Whose Design Does Not Privilege Any Individual Seat (Common Space Initiative, Beirut).
We envision a world where peace and nonviolence are the reality for for all children.
Our mission is to catalyze social change processes with local partners to advance just peace.
We partner with a global community of peacemakers to advance just peace. We work by invitation. In collaboration with local, national and international partners we help stakeholders develop peace and national change processes to transform conflict. These processes are usually long-term, multifaceted and involve a multiplicity of interdependent individual and institutional actors, initiatives and ideas, a veritable "ecosystem of peacebuilding." Our efforts encompass three distinct, but mutually reinforcing elements:
Peace Structures- we work with local partners to catalyze and develop institutions and other formal, as well as informal, structures and programs to support dialogue across many divides and negotiations. (See "Where We Work" for further information on several of the 7 distinct structures we have helped catalyze, e.g. Sri Lanka's One Text Initiative, the Nepal Transition to Peace Initiative, the Beirut based Common Space Initiative, Cyprus' Cyprus Dialogue Forum, etc.)
Knowledge Resources - we assist stakeholders in developing and disseminating the broad range of tools, research and information resources needed to enhance effective peace and conflict transformation efforts.
Human Capital - we support key local actors and changemakers in facilitating and advising national change processes, fielding international experts as requested and appropriate.
In the conduct of our work, we subscribe to and promote several core values and principles:
Inclusivity – processes must embrace the diversity of national stakeholders if they are to take root.
Authenticity - processes must both be owned by and reflect the cultures, traditions and needs of local stakeholders.
Innovation – processes must constantly adapt to the changing realities of the dynamic systems underlying political conflicts.
Independence – individuals and institutions serving these processes must preserve strict independence while simultaneously being engaged with, and understanding of, each party's interests.
The Peace Appeal Foundation is a largely volunteer network of committed individual and institutional stakeholders, including our Board of Directors, Support Staff, Volunteers, Associates, Advisors, Institutional Partners and Local Counterparts.
Since our founding, we have chosen to work flexibly through, or in partnership with other institutions, as the conditions in the countries we work necessitates. The focus of our efforts is always on the processes and initiatives we serve, regardless of shifting winds or priorities of government and private donors. Our partnerships with local institutions, many of which we helped nurture into being, continue far beyond our physical presence on the ground.
The Peace Appeal Foundation is not a grantmaking institution. We mobilize resources, human, financial and knowledge, for institutions and processes on the ground in countries in conflict. Most of these resources flow directly to our partners, not through the Peace Appeal Foundation.
Peace Support
The Peace Appeal Foundation's major area of program focus is Peace Support, aiding stakeholders in conflict design and implementation of processes and supporting structures that facilitate the just resolution of entrenched (often violent) national conflicts. Through our institutional network the Peace Appeal Foundation brings knowledge, expertise and financial resources together to aid local parties in these efforts. For further information on the specific initiatives in Southeast Asia, South Asia and the Middle East which we support, please see: "Where We Work."
Peace Education and Research
Since the Peace Appeal's inception, peace education and research have been a core component of our efforts. Our co-founders were pioneers in non-violence education and promoting media as a tool of conflict resolution. Their efforts contributed to the launch and promotion of the Appeal of the Nobel Peace Laureates for Peace and Non-Violence for the Children of the World, which played a central role in launching the United Nations Decade for the Promotion of a Culture of Non-Violence. For more on these efforts, please see "Our History." Today our peace education and research efforts are both integral as well as complementary to our peace support initiatives in countries in conflict, and include the following components:
Physical and Virtual Libraries for Peacebuilding
The Peace and Dialogue Platform
Educating the Next Generation of Peacemakers
Peace Advocacy
As international peacebuilding efforts have come to increasingly rely upon broad coalitions of governmental and non-governmental action stretching the resources and attention of the international community, the Peace Appeal works with national and international networks to draw attention to the needs and opportunities for direct assistance to countries in conflict. Concurrent with seeking to raise awareness of both the needs and opportunities, we are working to improve the international regulatory environment affecting and resources devoted to peacebuilding initiatives. In particular, we work with several coalitions (e.g. the Alliance for Peacebuilding and the Charity and Security Network) in promoting peacebuilding and studying and educating policymakers on the unanticipated impact on humanitarian relief and peacebuilding efforts in countries of conflict of many of the anti-terrorism laws passed in the years leading up to the September 11, 2001 attacks on the United States and in their wake.
Copyright 2019, Peace Appeal Foundation. All rights reserved.


In continuation of yesterday's post about getting involved in inspiring the next generation, without further ado, I give you Mentoring: Intermediate Mode!
Ok, so as much as you would really love to, you just don't have the time to be mentor. I get it – it is a huge commitment! That doesn't mean you can't become directly involved in some way. Check to see if a local school would be willing to let you come and talk to a few classrooms about your work/research one day. Find out if they have a family science night that you could set up a little table display for and chat with the kids and their families one night. Host a demonstration or workshop at your local public library. See if there is a Teen Science Cafe member within reasonable driving distance of you that is looking for presenters. This organization hosts free, casual events where local teens come to learn from a STEM professional about their research and do a related hands-on science activity. I can vouch that they are super fun for both the teens and the presenters! There are so many ways to get involved. Start getting creative, and get yourself out there!
Pictured: Some of the marine mammal trainers at work speaking to teens at a Teen Science Cafe.


text:
Home » The Mirror News » Prom Coast Seachange Festival rolls in
Prom Coast Seachange Festival rolls in
Added 24 Apr 2013 | Added by: The Mirror | Last updated 24 Apr 2013 by Administrator ⋅ Post a comment
Tags: Festivals
IT HAS been two years since the last one and this year's Prom Coast Seachange Festival promises to be bigger and better than ever. After months of careful preparation, finally this week the eagerly anticipated festival is here.
Deputy Premier and Member for Gippsland South Peter Ryan will officially open the festival this Friday evening in Foster's main hall.
Featuring more than 40 events showcasing the creativity, culture, lifestyle and landscape of the Prom Coast region, the Seachange Festival will run until Monday.
"The Seachange Festival is a great example of communities coming together, pooling their talents, and building an event that draws wide attention to this magnificent region," Mr Ryan said.
"Events such as the Sunday Street Food Festival, the Port Franklin Fresh Fish Lunch and the Sustainable Farm and Food Tour are great examples of how local producers and traders can promote their wares and provide an authentic and enjoyable experience for festival-goers."
Chair of the festival organising committee Deb Bray said the Prom Coast Seachange Festival celebrates the Prom Coast as a region with a diversity of opportunity that makes it a great place to live in or visit.
"What better way to get to know an area and its community than to join in when there's an event that showcases its people, products and places!" Mrs Bray said.
"The festival's program of events is rich and wide-ranging and is a result of the enthusiasm and hard work of locals, community groups, traders and regional agencies in organising and supporting events.
"Equally, we have to thank our sponsors, Tourism Victoria, Esso and BHP Billiton, Toora & Foster Community Bank® branches and South Gippsland Shire Council for their funding and support."
The festival will run from April 25 to 29, and program brochures are available from a variety of local shops, galleries, cafes and from Bendigo Bank branches.
Mr Ryan will officially open the festival at 6pm on Friday at the Foster War Memorial Arts Centre.
Further details about events and bookings can be found online at www.promcoastseachangefestival.org or via the festival's Facebook page.
Comments are disallowed for this post.